一、 事務基礎與 ACID 特性
事務是數據庫邏輯工作單元,具備 ACID 四大特性:
- 原子性:操作要麼全做,要麼全不做
- 一致性:事務前後數據庫保持一致狀態
- 隔離性:並發事務互不干擾
- 持久性:提交後修改永久生效
二、 SQL 標準定義的四級隔離
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 備註 |
Read Uncommitted (讀未提交) | ✅ 發生 | ✅ 發生 | ✅ 發生 | 性能最好,極少實用 |
Read Committed (讀已提交) | ❌ 避免 | ✅ 發生 | ✅ 發生 | 大多數 DB 默認(MySQL 除外) |
Repeatable Read (可重複讀) | ❌ 避免 | ❌ 避免 | ⚠️ 可能發生 | MySQL InnoDB 默認,MVCC 緩解幻讀 |
Serializable (可串行化) | ❌ 避免 | ❌ 避免 | ❌ 避免 | 最高隔離,鎖開銷大,並發低 |
關鍵現象定義
- 髒讀:讀到未提交事務的修改,後該事務回滾導致數據錯誤
- 不可重複讀:同一事務兩次查詢同一行,結果不一致(被其他事務更新)
- 幻讀:同一事務兩次範圍查詢,行數不一致(被其他事務插入/刪除)
三、 MySQL 實測驗證過程
測試環境:表 test(id int, name varchar),初始數據 (1, 'a')。雙客戶端 A、B 交互驗證。
1. Read Uncommitted —— 髒讀複現
- A 開啟事務查詢 → B 開啟事務更新未提交 → A 再次查詢 看到未提交修改 → B 回滾 → A 再查 數據恢復原值
2. Read Committed —— 不可重複讀複現
- A 開啟事務查詢 → B 更新並提交 → A 再次查詢 看到新值,兩次結果不一致
3. Repeatable Read —— 可重複讀與幻讀
- A 開啟事務查詢 → B 更新提交 → A 再查 仍見舊值(可重複讀生效)
- B 插入新行提交 → A 再查 未見新行(MVCC 快照隔離) → A 提交後重新查詢 見新行
注意:InnoDB 通過 MVCC(多版本並發控制)在 RR 級別實質上避免了幻讀,但標準定義仍標記「可能發生」。
4. Serializable —— 完全串行
- A 開啟事務查詢 → B 嘗試插入 阻塞等待 → A 提交 → B 成功插入
該級別對讀操作加共享鎖,寫操作排他鎖,實現真正串行,但極大降低並發吞吐。
四、 隔離級別設置與查看
-- 查看當前會話級別
SELECT @@transaction_isolation;
-- 設置會話級別
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 設置全局級別(需重連生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
五、 總結與選型建議
- 默認 RR 滿足絕大多數業務,MVCC 提供無鎖一致性讀
- 嚴格金融對賬可考慮 Serializable,接受性能代價
- 長事務、高並發場景慎用高隔離級別,評估鎖競爭風險
- 應用層可通過樂觀鎖(版本號)補償低隔離級別的並發問題