SELECT ... LOCK IN SHARE MODE,兼容 S,阻塞 XSELECT ... FOR UPDATE、UPDATE/DELETE/INSERT,阻塞 S/XInnoDB 默認行鎖(索引命中時),無索引退化為表鎖。
事務 A 鎖表 1 → 鎖表 2;事務 B 鎖表 2 → 鎖表 1。
UPDATE t1 JOIN t2 ... SET ...)-- 事務 A
SELECT * FROM t WHERE id=1 LOCK IN SHARE MODE; -- 持有 S 鎖
UPDATE t SET c=2 WHERE id=1; -- 嘗試升級為 X 鎖
-- 事務 B
UPDATE t SET c=3 WHERE id=1; -- 持有 X 鎖,阻塞 A 升級
-- A 持有 S 阻塞 B 獲取 X → 死鎖
| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| 前端防重(按鈕置灰) | 源頭阻斷並發請求 | 零代碼改動 | 不可靠(繞過前端失效) |
| 樂觀鎖 (版本號/時間戳) | 更新時校驗 version,失敗重試 | 無鎖開銷,高並發性能優 | 外部系統繞過易髒寫;需業務容忍重試 |
| 悲觀鎖 (FOR UPDATE) | 查詢即加 X 鎖,串行化 | 強一致性,簡單 | 長事務鎖阻塞嚴重,並發差 |
**推薦**:核心業務「樂觀鎖 + 重試」為主,「前端防重」輔助;極少數強一致場景(如扣款)用「悲觀鎖 + 短事務」。
EXPLAIN 分析 SQL,消除 type=ALL鎖衝突 90% 源於**應用代碼設計缺陷**(順序、索引、事務大小、併發控制),而非數據庫本身。質量內建於設計編碼階段,測試只能驗證,不能創造質量。
EXPLAIN 核心 SQL,消除全表掃描Innodb_row_lock_waits、Innodb_row_lock_time_avg 指標鎖是保護數據一致性的盾,用不好就是傷害性能的刀。懂原理、守規範、重設計,才能讓並發系統穩如磐石。