問題描述
當應用程序頻繁讀寫某個表或者資源時,容易出現死鎖現象。出現死鎖時,SQL Server會選擇終止其中一個事務,并且向發起該事務的客戶端發送類似如下的錯誤信息:
Error Message:Msg 1205, Level 13, State 47, Line 1Transaction (Process ID 53) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
解決方案
使用客戶端連接實例。具體操作,請參見連接SQL Server實例。
監控相關視圖。
執行如下SQL語句,循環監控
SYS.SYSPROCESSES
。WHILE 1 = 1 BEGIN SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0; WAITFOR DELAY '[$Time]'; END;
說明您可以自定義
[$Time]
循環間隔時間,此處以00:00:01
為例。系統顯示類似如下:
說明監控結果中
blocked
列的值為阻塞該會話的阻塞源會話ID,waitresource
為被阻塞的會話等待的資源。從上述結果可以看到,spid 53和spid 56相互阻塞,形成了死鎖。執行如下SQL語句,循環監控
sys.dm_tran_locks
和sys.dm_os_waiting_tasks
等視圖。while 1=1 Begin SELECT db.name DBName, tl.request_session_id, wt.blocking_session_id, OBJECT_NAME(p.OBJECT_ID) BlockedObjectName, tl.resource_type, h1.TEXT AS RequestingText, h2.TEXT AS BlockingText, tl.request_mode FROM sys.dm_tran_locks AS tl INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1 CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2 waitfor delay '[$Time]' End
系統顯示類似如下:
返回參數說明如下:
參數
說明
DBName
request_session_id操作的數據庫。
request_session_id
當前請求的會話ID,即被阻塞的會話。
blocking_session_id
阻塞源會話ID。
BlockedObjectName
被阻塞的會話操作的對象。
resource_type
等待的資源類型。
RequestingText
當前會話執行的語句,即被阻塞的語句。
BlockingText
阻塞源會話執行的語句。
request_mode
當前會話請求的鎖模式。
如果您的實例版本是RDS SQL Server 2012,還可以使用SQL Server Profiler來監控和抓取死鎖圖譜,如下所示:
抓取的死鎖圖譜如下所示:
調優建議
可以參考以下步驟,進行調優。
關閉阻塞源會話,可以幫助快速解除阻塞。
查看是否有長時間未提交的事務,及時提交事務。
如果有S鎖導致的死鎖,并且您的應用允許臟讀,可以使用
WITH (NOLOCK)
查詢提示。例如在查詢中寫入SELECT * FROM table WITH (NOLOCK);
使查詢在執行時避免申請鎖,從而避免死鎖。檢查應用程序邏輯,按順序訪問某個資源。
相關操作
您可以在RDS控制臺查看RDS SQL Server數據庫中的死鎖及其詳細信息。更多詳情,請參見死鎖。