我使用在ASP.NET頁面下面的代碼創建一個記錄,然後計算記錄,以確保我未超過設定的限制,如果我有回滾事務。NHibernate的死鎖
using (var session = NhibernateHelper.OpenSession())
using (var transaction = session.BeginTransaction())
{
session.Lock(mall, LockMode.None);
var voucher = new Voucher();
voucher.FirstName = firstName ?? string.Empty;
voucher.LastName = lastName ?? string.Empty;
voucher.Address = address ?? string.Empty;
voucher.Address2 = address2 ?? string.Empty;
voucher.City = city ?? string.Empty;
voucher.State = state ?? string.Empty;
voucher.Zip = zip ?? string.Empty;
voucher.Email = email ?? string.Empty;
voucher.Mall = mall;
session.Save(voucher);
var issued = session.CreateCriteria<Voucher>()
.Add(Restrictions.Eq("Mall", mall))
.SetProjection(Projections.Count("ID"))
.UniqueResult<int>();
if (issued >= mall.TotalVouchers)
{
transaction.Rollback();
throw new VoucherLimitException();
}
transaction.Commit();
return voucher;
}
但是,我遇到了很多的死鎖。我想這會發生,因爲我試圖計數表中的記錄,我只是執行了一個插入和一個鎖仍然保持在插入的行,導致死鎖。
- 任何人都可以證實這一點?
- 任何人都可以提出修復方案嗎?
我試着在最終查詢上調用SetLockMode(LockMode.None),但是這導致NullReferenceException,我找不出來。
編輯:如果我在保存對象之前運行查詢,它可以工作,但是我沒有完成驗證我的插入沒有超出限制的目標(在併發插入的情況下) 。
編輯:我發現,在session.BeginTransaction呼叫使用IsolationLevel.ReadUncommited解決了這個問題,但我沒有數據庫專家。這是適當的解決方案,或者我應該如何調整我的邏輯?
從理論上講,憑證將永遠不會被刪除,甚至更新。此外,我傾向於避免性能方面的觸發器(儘管純度也很好)。 – Chris 2009-08-04 21:00:48
但是讓我們說優惠券經常被刪除。確保通過插入優惠券的正確方法是什麼?我從來沒有超過任何限制? – Chris 2009-08-04 21:01:50