2010-03-01 50 views
0

我的一位同事的存儲過程執行以下操作:
Begin tran
1)動態生成select語句。
2)插入到表X
3)執行SELECT語句
結束TRANSQL 2008 SP - 死鎖原因還是紅鯡魚?

如果此存儲過程是通過同時在兩個隔線程跑了,他得到了以下錯誤: System.Data.SqlClient.SqlException :事務(進程ID 57)在lock |上死鎖通信緩衝區資源與另一個進程並被選爲死鎖受害者。重新運行

這個存儲過程真的是這個問題嗎?從我的天真頭腦來看,這看起來更糟糕的是競賽狀況,而不是僵局。

+0

select語句還創建鎖。可能步驟1和3在兩個線程中爲相同的記錄而戰。 – 2010-03-01 22:17:01

回答

1

兩個'寫入然後讀取'序列可以定義死鎖。您在文章中省略了一些「詳細信息」,例如死鎖發生的實際資源以及涉及的請求。我們將乘坐褲子坐在飛機上閱讀,從這樣一篇文檔不佳的文章中彌補了大部分情況:

  1. 交叉讀寫。線程1用鍵A插入行,然後用鍵B選擇行。線程2用鍵B插入行,然後用鍵A選擇行。執行順序是T1(A),T2(B),T1(B) - 等待,T2 (A)-deadlock。
  2. 獨立寫入讀取:T1插入A然後讀取A,T2插入B然後讀取B.關鍵信息:在關鍵字上沒有索引,因此需要Tabel掃描來讀取A和/或B。執行順序是T1寫入A,T2寫入B,T1讀取A,開始掃描,T2在B上鎖定X鎖,T2讀取B,開始掃描,阻塞T1在X上鎖定A,死鎖。
  3. Independence optimized write-read。對於大多數新手來說,這種情況是最合適的,當適當的訪問索引到位時,仍然會出現死鎖。我在Read/Write deadlock中介紹過這種情況,由於索引訪問順序不同,更新可能導致讀取死鎖。不太可能是你的情況,但是如此糟糕的文檔,任何事情都是可能的。

許多更多的死鎖情況是可能的,但我們會輸入esoterics或開始推斷相當遠的OP中缺失的信息。

如果我冒險猜測,最有可能的情況是2)。情況1)可能很容易成爲標識符。情況2)在簡單的代碼分析中有點難以檢測,因爲它在物理模式設計(索引結構)上進行了分析。

0

在分析器中運行一個跟蹤(選擇空白模板),選擇死鎖圖形事件,然後在出現的新選項卡上(事件提取設置),將每個事件(單獨檢查保存死鎖XML事件)保存在其自己的文件。用xml查看器打開這個文件,很容易知道發生了什麼。每個進程都包含着一堆過程調用等,並且所有的鎖都在其中,所以你可以確定是什麼導致了死鎖。

讓這個跟蹤運行,直到死鎖再次發生,只有當發生死鎖時記錄信息,所以沒有太多開銷。