SQL Server進程死鎖

SQL Server遇到錯誤“事務(進程 ID 144)與另一個進程被死鎖在 鎖 | 通信緩衝區 資源上,並且已被選作死鎖犧牲品。請重新運行該事務。”之前也遇到過,上次沒解決,這次再看看。既然出現“死鎖”現象,問題肯定出在更新記錄表上,所以找到被鎖定的表,問題將會解決。找到出問題的存儲過程,發現存在以下update語句

update mytable set name='Daniel' 
where id in (select id from mytable where name like '%d%') ;

猜測,問題可能出在批量更新表上。關於鎖定記錄,網上有以下SQL代碼,使用with(updlock)關鍵詞演示記錄被鎖定時的情景。

--打開一個SQL查詢窗口,執行以下SQL語句
begin tran;
select * from mytable with(updlock) where id= 1;
update mytable set name = 'Kate'  where id=1;
waitfor delay '00:00:30';
commit tran;

--再打開一個SQL查詢窗口,執行以下SQL語句
update mytable set name = 'Lucy' where id=1;

--再打開一個SQL查詢窗口,執行以下SQL語句
update mytable set name = 'Fiona' where id=1;


執行結果是mytable中id等於1的記錄的name字段值爲'Finona',雖然過程中出現了等待,但最終還是成功執行了記錄。當一條記錄處於鎖定狀態時,其他更新SQL語句需要等待它解鎖,然後方可執行,如果超時,等待執行的SQL將會報“死鎖”錯誤,執行失敗。

本例中,批量更新表mytable時遇到錯誤,猜測待更新的記錄中存在已鎖定記錄,嘗試使用with(nolock)關鍵詞在篩選id時就剔除鎖定狀態的記錄。

經測試,這樣做確實不再出現“死鎖”情況,但也可能存在“漏”更新的記錄,這種“漏”掉的記錄或許會影響數據,也可能不影響。此時,需要從業務上評估其影響性。

綜上所述,解決類似問題有以下兩個途徑:

1、調整業務邏輯,確保sql執行順序合理

2、使用with(nolock)關鍵詞,不過可能存在“漏”更新的風險,想其他辦法處理。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章