3

我正在使用NHibernate作爲數據訪問層和SQL Server精簡版使用c#桌面應用程序。該應用程序使用多個線程來執行數據的選擇和更新。由索引上的頁面鎖定引起的sql server小型死鎖

一般來說它工作正常,但有時會出現死鎖的情況。

15:28:16750 55 WARN:System.Data.SqlServerCe.SqlCeLockTimeoutException(0X80004005):超時..... [會話ID = 28,線程ID = 14576,進程ID = 12960,表名稱= PatientOrder,Conflict type = x lock(x blocks),Resource = PAG(idx):1035]

如果兩個事務嘗試更新相同的行,我可以理解死鎖問題。但是在這種情況下,兩個交易都在不同行上工作。 這個死鎖看起來是由索引(Resource = PAG (idx): 1035)上的頁鎖造成的。

所以我的問題是:可以做些什麼來防止這些死鎖?

我已經調查了以下選項:

  • 禁用頁鎖索引。這是可能的「全」 SQL服務器,但似乎並沒有被精簡版支持

  • 配置Hibernate產生with(rowlock)的SQL語句會(希望)防止問題

  • 欲以session.lock(...)以所有事務的相同順序執行資源訪問。然而這似乎沒有幫助,因爲死鎖事務處理在不同的行上

  • 序列化所有數據庫事務,以便一次只有一個事務處於活動狀態。這確實有效,但會對性能產生重大影響。

回答

0

@Wolfgang你是如何管理你的ISession的? ISession不是線程安全的,如果您使用單個實例並在線程之間共享,這應該是您的問題。如果您使用的是IoC,請驗證ISession的範圍,將其更改爲每個線程一個。