首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL InnoDB 間隙鎖死鎖實戰:非匹配 UPDATE 也會加鎖的反直覺真相

     編輯:MySQL 綜合教學

MySQL InnoDB 間隙鎖死鎖實戰:非匹配 UPDATE 也會加鎖的反直覺真相

認知盲區:**WHERE 條件不匹配任何行的 UPDATE/DELETE,InnoDB 依然會加間隙鎖(Gap Lock)**,導致極易發生死鎖。本文通過最小復現案例揭示機制與規避方案。

最小復現場景

Session 1: UPDATE ... WHERE id=1  → 鎖定 Gap (-∞, 1] + (1, 2)  (Next-Key Lock)
Session 2: UPDATE ... WHERE id=2  → 鎖定 Gap (1, 2] + (2, +∞)
Session 1: INSERT (1)  → 需插入 Gap (1, 2)  → 被 Session 2 的 Gap Lock 阻塞 → WAIT
Session 2: INSERT (2)  → 需插入 Gap (1, 2] → 被 Session 1 的 Gap Lock 阻塞 → DEADLOCK
  → InnoDB 檢測到環路,選擇 Session 2 犧牲回滾

規避方案(四選一)

  1. 改用 READ COMMITTED 隔離級別(推薦):
    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
    RC 級別無間隙鎖,僅鎖定匹配行,**徹底消除此類死鎖**。需評估業務能否接受不可重複讀。
  2. 改用 REPLACE INTO / INSERT ... ON DUPLICATE KEY UPDATE:
    單條語句原子化「有則更新無則插入」,避免「先查後寫」間隙。
  3. 應用層樂觀鎖:
    版本號/時間戳字段,UPDATE ... WHERE id=? AND version=?,失敗則重試。
  4. 調整業務邏輯順序:
    避免「先 UPDATE 不存在行,再 INSERT 同鍵」模式;或統一按主鍵順序操作(減少交叉但不根治)。

驗證 READ COMMITTED 效果

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved