2008-09-23 160 views
1

我有一個ASP.NET應用程序使用NHibernate在用戶操作時事務性地更新一些表。有一個日期範圍涉及到,只有一個表格「預訂」的條目可以制定爲指定獨佔日期。NHibernate的交易和競爭條件

我的問題是如何防止兩個用戶動作幾乎同時發生的競爭條件,並導致多個條目進入'預訂'> 1日期。我在調用.Commit()之前無法檢查,因爲我認爲這仍然會導致競爭狀態?

我所能看到的只是在提交之後進行檢查,然後手動將更改返回,但這會讓我的口腔中感覺很不好! :)

booking_ref(INT)PRIMARY_KEY AUTOINCREMENT

booking_start(DATETIME)

booking_end(DATETIME)

回答

5
  • 讓您的交易SERIALIZABLE(session.BeginTransaction(IsolationLevel.Serializable)的隔離級別,檢查並插入相同的事務。一般情況下,不應該將isolationlevel設置爲可序列化,就像這樣。

  • 鎖表您檢查並在插入之前。你可以通過發起一個SQL查詢通過nhibernate來做到這一點:

    session.CreateSQLQuery(「SELECT null as dummy FROM Booking WITH(tablockx,holdlock)」)。AddScalar(「dummy」,NHibernateUtil.Int32); 這將僅鎖定該表以便在該事務處理期間選擇/插入。

希望它幫助

+0

當然 - 不敢相信我設法完全錯過了桌子鎖,心裏一片空白!非常感謝。 – 2008-09-23 11:12:59

-1

您的數據庫管理你的數據完整性。

你可以讓你的'日期'列唯一。因此,如果2個線程試圖獲得相同的日期。一個會拋出一個唯一的密鑰違規,另一個會成功。

0

上述解決方案可用作選項。如果我通過使用「Parallel.For」發送了100個請求,而事務級別是可序列化的,那麼沒有重複的請求id,但是25個事務失敗。這是我的客戶不能接受的。所以我們解決了只存儲請求標識並在其他表上添加唯一索引的問題。