死鎖是鎖基礎並發系統的必然產物。當兩個連線互相持有對方需要的鎖且均不釋放時,SQL Server 會自動選擇犧牲者回滾。雖然重試機制能緩解,但頻繁死鎖會嚴重拖垮吞吐量。本文從設計階段著手,構建全方位防死鎖策略。
READ COMMITTED SNAPSHOT (RCSI):讀取不加共享鎖,寫入不阻塞讀取,大幅減少死鎖機率SNAPSHOT ISOLATION:需應用層處理更新衝突,適合高併發低衝突場景BEGIN/COMMIT TRAN 置於 SP 內部,減少網路往返導致的鎖持有時間RowVersion (timestamp) 欄位WHERE ID=@id AND RowVer=@oldVer,@@ROWCOUNT=0 即觸發重試邏輯UPDLOCK/HOLDLOCK 等顯式鎖提示WAITFOR DELAY 釋放鎖READ_ONLY,更新遊標用 OPTIMISTIC,禁用 SCROLL_LOCKSxml_deadlock_report,自動解析死鎖圖LCK_M_* 等待趨勢-- 應用層偽碼 (指數退避 + 抖動)
for attempt in 1..MaxRetries:
try:
ExecuteTransaction()
break
catch DeadlockException:
if attempt == MaxRetries: throw
wait = Random(2^attempt * BaseDelay * 0.5, 2^attempt * BaseDelay * 1.5)
Sleep(wait)
關鍵:隨機抖動防止多個重試者同步再次衝突。
死鎖不可完全消除,但透過系統性工程,可將其頻率壓至業務可接受極低水準。