資料庫事務的四大基石——原子性、一致性、隔離性、持久性——構成了可靠資料處理的基礎。其中隔離性定義了併發事務之間的可見度邊界,SQL 標準將其劃分為四個等級:READ UNCOMMITTED、READ COMMITTED(RC)、REPEATABLE READ(RR)與 SERIALIZABLE。MySQL InnoDB 預設採用 RR,但生產環境中 RC 也廣泛使用(如淘寶、網易)。本文將深入剖析 RC 與 RR 在鎖機制、複制相容性、一致性視圖構建及半一致性讀等核心維度的差異。
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
|---|---|---|---|
| READ UNCOMMITTED | 允許 | 允許 | 允許 |
| READ COMMITTED (RC) | 禁止 | 允許 | 允許 |
| REPEATABLE READ (RR) | 禁止 | 禁止 | 允許* |
| SERIALIZABLE | 禁止 | 禁止 | 禁止 |
*註:MySQL RR 透過 Gap Lock(Next-Key Lock)實際上也解決了幻讀問題。
UPDATE 提交)。重點在修改。INSERT/DELETE 提交)。重點在新增/刪除。從實現角度看:防止不可重複讀只需鎖定滿足條件的記錄(SELECT ... FOR UPDATE);防止幻讀則需鎖定記錄及其間的間隙,即 Gap Lock。
除 MySQL 預設 RR 外,Oracle、PostgreSQL、SQL Server 等主流資料庫均預設 RC。Oracle 僅實現 RC 與 SERIALIZABLE 兩級。MySQL 選擇 RR 作為預設,主要考量Binlog 複制相容性(詳見下文)。
MIXED 或 ROW 格式。這也是 MySQL 預設 RR 的歷史原因——早期版本僅支援 Statement 格式。binlog_format=ROW。SELECT 語句執行瞬間,都會建立一個獨立的 ReadView,讀取該時刻已提交的資料快照。SELECT 執行時建立 ReadView,作為整個事務的一致性快照基準。後續查詢均基於此快照,實現「可重複讀」。Semi-Consistent Read 僅在 RC 隔離級別(或開啟 innodb_locks_unsafe_for_binlog)下生效。
運作流程:
UPDATE 掃描到已加鎖記錄時,InnoDB 返回最新提交版本給 MySQL Server 層;WHERE 條件;優勢:大幅減少 UPDATE 語句的行鎖衝突,對於大量不符合條件的記錄可提前放鎖,提升併發效能。RR 下 UPDATE 直接使用當前讀,遇鎖必須等待。
MySQL RC 與 RR 的差異本質上是鎖策略激進度與一致性視圖生命週期的權衡。RC 通過釋放無效鎖、半一致性讀優化更新併發,適合現代高吞吐系統;RR 通過統一 ReadView 與 Gap Lock 提供更強一致性保證,適合傳統事務密集型應用。理解這些機制差異,才能根據業務特性做出最優架構決策。