事務四大特性(ACID)
| 特性 | 含義 |
| 原子性 | 事務內所有操作要麼全做,要麼全不做 |
| 一致性 | 事務前後數據庫從一個一致性狀態轉換到另一個 |
| 隔離性 | 併發事務互不干擾,內部操作對其他事務不可見 |
| 持久性 | 提交後的修改永久生效,不受後續故障影響 |
InnoDB 鎖類型與加鎖語句
| 語句 | 鎖類型 | 兼容性 | 備註 |
SELECT ... LOCK IN SHARE MODE | 共享鎖 (S) | 兼容 S,阻塞 X | 讀取並防止他人修改 |
SELECT ... FOR UPDATE | 排他鎖 (X) | 阻塞 S/X | 讀取並防止他人讀寫 |
INSERT/UPDATE/DELETE | 排他鎖 (X) | 阻塞 S/X | 隱式加鎖 |
| 範圍查詢 | 間隙鎖 / Next-Key Lock | 阻塞插入 | 防止幻讀,鎖定不存在的區間 |
⚠️ 具體加鎖行為還受 事務隔離級別 影響
四大隔離級別對比
| 級別 | 髒讀 | 不可重複讀 | 幻讀 | 備註 |
| READ UNCOMMITTED | ✅ 可能 | ✅ 可能 | ✅ 可能 | 性能最好,極少用 |
| READ COMMITTED | ❌ | ✅ 可能 | ✅ 可能 | Oracle 默認,RC |
| REPEATABLE READ | ❌ | ❌ | ❌ (MVCC+Gap Lock) | InnoDB 默認,RR |
| SERIALIZABLE | ❌ | ❌ | ❌ | SELECT 自動加 S 鎖,串行化 |
實戰驗證:同一行在不同隔離級別下的可見性
測試表 account(id PK, vaccount_id, gmt_create),10 萬行數據。
READ UNCOMMITTED:可見未提交修改(髒讀)
T1: START TRANSACTION; SELECT vaccount_id FROM account WHERE id=1001; -- caimao101510
T2: START TRANSACTION; UPDATE account SET vaccount_id='uncommitted' WHERE id=1001;
T1: SELECT vaccount_id FROM account WHERE id=1001; -- uncommitted (髒讀)
T2: ROLLBACK;
T1: SELECT vaccount_id FROM account WHERE id=1001; -- caimao101510
READ COMMITTED:不可重複讀
T1: START TRANSACTION; SELECT ...; -- caimao101510
T2: START TRANSACTION; UPDATE ... SET vaccount_id='uncommitted'; COMMIT;
T1: SELECT ...; -- uncommitted (前後兩次讀不一致)
REPEATABLE READ:可重複讀(InnoDB 默認)
T1: START TRANSACTION; SELECT ...; -- caimao101510
T2: START TRANSACTION; UPDATE ... SET vaccount_id='uncommitted'; COMMIT;
T1: SELECT ...; -- caimao101510 (仍舊讀到舊值,MVCC 快照)
最佳實踐建議
- 默認使用 REPEATABLE READ,滿足絕多數業務一致性需求
- 長事務、高併發場景評估 READ COMMITTED + 悲觀鎖/樂觀鎖
- 明確需要串行化時才用
SERIALIZABLE 或應用層分布式鎖
- 善用
SELECT ... FOR UPDATE / LOCK IN SHARE MODE 顯式控制併發
- 監控
INNODB_LOCK_WAITS、INNODB_TRX 定位死鎖/長事務