SQL Server併發操做單個表時發生在page頁面級的死鎖

 

最近遇到的死鎖問題都發生在併發操做單張表上,比較有意思,就模擬了重現了一下。
根據非彙集索引爲條件,刪除某一個表的數據,相似於這麼一個語句,delete from table where nocluster_index in (x,y,z,m,n……)in裏面的內容不一樣,併發執行
某些狀況下,可能會引起死鎖,以下簡單模擬重現一下這種狀況。併發

 

以下用兩張表來模擬上述場景:TestPageLock表明要刪除的表,TestId來存儲用來刪除的Id性能

 

以下,用兩個Session便可,模擬併發,很快就會看到一條死鎖的信息測試

 

擴展事件ring_buffer target中中的死鎖日誌日誌

原理不難理解:
不一樣的Session要刪除的數據分佈在不一樣的數據頁面中,執行delete語句刪除數據的狀況下,也是一個查找而後加鎖的過程
當要刪除的數據落在不一樣的數據頁面上的時候,一旦加鎖順序發生衝突,就會產生死鎖
好比Session1刪除的數據分佈在50,80,120頁面上,Session2刪除的數據分佈在100,120,140頁面上,
Session1和Session2 要加鎖的目標存在交集,一旦存在交集,併發狀況就可能存在加鎖順序衝突,相似死鎖所以而產生blog

 

解決:
最最簡單暴力的就是顯式鎖提示,這裏只能是tablockx;高級一點,遇到相似併發業務,可使用隊列進行排隊。
估計會有人擔憂tablockx的性能問題會不會鎖的太多了,測試發現直接顯式tablockx鎖提示,並不會很是大地影響性能,總體性能甚至會變高,
由於tablockx鎖模式更加簡單直接,會比行數須要的資源更少,所以在鎖定資源上,處理起來比較高效。索引

相關文章
相關標籤/搜索