2011-09-11 116 views
3

我有一個偶爾會導致數據庫死鎖的WCF服務。我的服務允許您向理事會提交申請,也允許您再次加載申請,因爲理事會可以更新它們。每個應用程序都有許多與之關聯的文檔。如何避免緩慢查詢造成的死鎖

所以,如果發生在我服務的一組這樣的事件

1) Application #1 is submitted 
2) A document is uploaded for application #1 
3) Application #1 is loaded 
4) Part 2 above finishes 

僵局部分3.我相信原因是,在第2部分文件需要一段時間才能從提交到SQL服務器WCF服務,並在此期間鎖定表。

因此,如果我們從數據庫應用程序#1加載,並且遇到問題的相關文檔。

我正在使用實體框架。我該如何解決這個問題?我真正想要做的就是在這種情況下加載文件,這些文件完全被提交,並且不會被鎖入表格或任何東西中。

通過,這是我收到的特定錯誤的方式,

Message: Transaction (Process ID 93) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. 

更新:我有一對夫婦,我可以改變操作的順序意見。我不能這樣做,因爲第2部分和第3部分來自對WCF服務的不同調用。所以服務的用戶需要定購這些操作。 '要求他們改變'你說,但也不是那麼簡單。操作的順序實際上取決於最終用戶恰好在恰當的時刻「刷新」瀏覽器。

更新#2:我需要一些關於如何複製此問題的建議。我已經寫了一個測試應用程序,上面的第2部分確實阻止了第3部分的操作,但對我的影響是操作3只是阻塞,直到操作2完成,然後操作3結束。

因此,這意味着第3部分需要1分50秒,而不是3分。任何想法爲什麼它會阻止我,而不是造成僵局?它可能與該服務器上整體數據庫流量的數量有關,因爲我正在使用測試服務器,或者某些數據庫設置可能會影響它?

回答

1

有幾種方法,以避免在一般的死鎖(SQL Server等數據庫):

1)只在事務結束通話saveChanges(),執行所有查詢到一起。

2)更改順序以執行數據庫更新,首先執行所有讀取(SELECT)並最後執行所有更新。

3)從事務中沒有修改的數據的事務中讀出數據。

4)如果應用程序邏輯允許,將事務的隔離級別更改爲SERIALIZABLE(性能較差)或SNAPSHOT或沒有像READ UNCOMMITTED這樣的鎖定的其他中間級別。

5)使用lock(lock_object)創建同步代碼塊,以避免兩個線程並行執行同一事務或執行兩個鎖定自己的不同事務。

+0

我已經更新了這個問題。我無法真正控制操作的順序。我的解決方案必須與你的答案的第4或5部分相關。第5部分聽起來似乎不太可能,因爲可能有一些線程同時運行。 – peter

+0

您可以運行多個線程,但您只需要同步執行導致死鎖的操作的代碼部分。這會降低整體吞吐量,但另一種選擇是更改隔離級別以避免鎖定。 SNAPSHOT隔離級別,SQL Server 2005中的新增功能嘗試解決死鎖問題;而不是在更改數據時創建鎖,存儲不同版本的數據,並且每個事務讀取所需數據的版本。 –

+0

我已經勾選了你的答案,因爲它是第一個。我認爲這個問題可以得到緩解。導致死鎖的查詢是從數據庫(blob)中拉出一個不需要的字段。這意味着通過從查詢中刪除該字段將使查詢更快,從而在表被鎖定時不太可能發生。找出真正的問題會變得更加困難,因爲我所看到的確定它可能會導致阻塞,但找出實際上導致死鎖的因素會變得更加複雜。 – peter

1

一對夫婦的解決方案:

  • 使用讀取未提交的隔離級別,如果你不介意的話可能有未提交的行步驟3(這取決於您的情況)出現。

OR

  • 批量貴就貴EF背景下更有效地並更改確保他們執行一次全部(沒有看到你的代碼,我不知道你是否這樣做或不)

編輯

下面的鏈接也可以有助於解決問題和修復您的問題:

http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx

+0

我無法控制操作的順序。我已經更新了我的問題。我的解決方案必須與我認爲的隔離級別相關。 – peter