從SQL Server的Online Book裡面描述Deadlock策略裡面發現有下面的一種情況:
Worker threads. A queued task waiting for an available worker thread can cause deadlock. If the queued task owns resources that are blocking all worker threads, a deadlock will result. For example, session S1 starts a transaction and acquires a shared (S) lock on row r1 and then goes to sleep. Active sessions running on all available worker threads are trying to acquire exclusive (X) locks on row r1. Because session S1 cannot acquire a worker thread, it cannot commit the transaction and release the lock on row r1. This results in a deadlock.
- 背景工作執行緒。排隊等待可用背景工作執行緒的任務可能導致死結。如果排隊等待的任務擁有阻塞所有背景工作執行緒的資源,則將導致死結。例如,會話 S1 啟動事務並擷取行 r1 的共用鎖定(S 鎖)後,進入睡眠狀態。在所有可用背景工作執行緒上啟動並執行活動會話正嘗試擷取行 r1 的獨佔鎖定(X 鎖)。因為會話 S1 無法擷取背景工作執行緒,所以無法提交事務並釋允許存取 r1 的鎖。這將導致死結。
也就是說並不一定要是都是Update、Insert這種會上排它鎖操作的語句才會造成死結。只要在不同的線程裡面訪問了同一個資源(某個資料行)的情況下,一個Select動作碰上了一個Update動作也會產生死結。你的SQL語句執行時間越長碰上這種情況的機會越大。看看下面這張圖
左邊的進程完全就是一個普通的查詢語句,對資源上的也只是一個共用鎖定(S).而右邊的進程是上了一個Index的排它鎖(IX).跟通常意義上的兩邊都上排它鎖才可能產生死結的情況完全不一樣,下面的圖是我們寫程式可以避免的死結情況
怎麼處理好SQL Server裡面的死結的話可以參照下面這篇文章:
Reducing SQL Server Deadlocks
裡面提到了,要避免的Deadlock,把不同事務裡面兩個Update或者Insert資源的伺服器用戶端檔案鎖資源順序保持一致是最基本的,不過也就是能避免第二張圖裡面出現的情況。
-