應用執行 UPDATE 時拋出 DeadlockLoserDataAccessException,資料庫自動回滾重試,用戶感知為操作卡頓,監控系統持續報警。
private void updateWithDeadLockRetry(Mapper mapper, Record record) {
int maxRetries = 5;
for (int attempt = 0; attempt < maxRetries; attempt++) {
try {
mapper.updateByPrimaryKeySelective(record);
return; // 成功即返回
} catch (DeadlockLoserDataAccessException e) {
if (attempt == maxRetries - 1) throw e; // 最後一次仍失敗則拋出
long sleepMs = (long) (Math.random() * 500) + (attempt * 100); // 指數退避+抖動
Thread.sleep(sleepMs);
}
}
}
關鍵點: 限制重試次數、引入隨機延遲避免雷群效應、記錄重試日誌便於事後分析。
SELECT ... LOCK IN SHARE MODE 獲取,允許並發讀、阻塞寫UPDATE/DELETE 獲取,阻塞所有其他鎖SELECT * FROM t WHERE i=1 LOCK IN SHARE MODE → 持有 S 鎖DELETE FROM t WHERE i=1 → 需要 X 鎖,被 A 的 S 鎖阻塞,等待中DELETE FROM t WHERE i=1 → 需要 X 鎖,但 B 已持有 X 鎖等待 → 循環等待形成死鎖InnoDB 偵測到死鎖後,選擇代價較小的事務(通常是修改行數較少者)為犧牲者回滾,釋放鎖資源,另一事務繼續執行。
SHOW ENGINE INNODB STATUS 定期檢視死鎖歷史