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

MySQL 隔離級別 RC 與 RR 深度解析:核心差異與選型指南

     編輯:MySQL 綜合教學

前言:事務 ACID 特性回顧

資料庫事務的四大基石——原子性、一致性、隔離性、持久性——構成了可靠資料處理的基礎。其中隔離性定義了併發事務之間的可見度邊界,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)實際上也解決了幻讀問題。

核心概念辨析

  • 髒讀:讀取未提交資料。RC 以上級別均禁止。
  • 不可重複讀:同一事務多次查詢同一行,值發生變化(被他事務 UPDATE 提交)。重點在修改。
  • 幻讀:同一事務多次查詢同一範圍,行數增減(被他事務 INSERT/DELETE 提交)。重點在新增/刪除。

從實現角度看:防止不可重複讀只需鎖定滿足條件的記錄(SELECT ... FOR UPDATE);防止幻讀則需鎖定記錄及其間的間隙,即 Gap Lock。

二、預設隔離級別的選擇差異

除 MySQL 預設 RR 外,Oracle、PostgreSQL、SQL Server 等主流資料庫均預設 RC。Oracle 僅實現 RC 與 SERIALIZABLE 兩級。MySQL 選擇 RR 作為預設,主要考量Binlog 複制相容性(詳見下文)。

三、RC 與 RR 核心差異深度對比

3.1 鎖機制差異:Gap Lock 與鎖釋放策略

  1. Gap Lock 存在性:RR 支援 Gap Lock(Next-Key Lock)以防幻讀;RC 無 Gap Lock,允許幻讀與不可重複讀,因此 RC 並發吞吐通常優於 RR 。
  2. 不符合 WHERE 條件記錄的鎖處理:RC 下,掃描過濾後不符合條件的記錄,行鎖會即時釋放(雖違反「兩階段鎖協議」);RR 下則保持行鎖與 Gap Lock 不釋放。這使得 RC 在大範圍掃描更新時鎖衝突更低。

3.2 複制相容性:Binlog 格式限制

  • RC 隔離級別不支援 Statement 格式 Binlog,因語句級複制在 RC 下會導致主從資料不一致;必須使用 MIXED 或 ROW 格式。這也是 MySQL 預設 RR 的歷史原因——早期版本僅支援 Statement 格式。
  • MySQL 5.6 早期版本允許 RC 使用 Statement 格式,後期版本直接報錯。生產環境強烈建議統一設定 binlog_format=ROW。

3.3 一致性讀視圖構建時機

  • RC:事務中每一條 SELECT 語句執行瞬間,都會建立一個獨立的 ReadView,讀取該時刻已提交的資料快照。
  • RR:事務中第一條 SELECT 執行時建立 ReadView,作為整個事務的一致性快照基準。後續查詢均基於此快照,實現「可重複讀」。

3.4 半一致性讀:RC 獨有的更新優化

Semi-Consistent Read 僅在 RC 隔離級別(或開啟 innodb_locks_unsafe_for_binlog)下生效。

運作流程:

  1. UPDATE 掃描到已加鎖記錄時,InnoDB 返回最新提交版本給 MySQL Server 層;
  2. Server 層判斷該版本是否滿足 WHERE 條件;
  3. 若不滿足,直接跳過,不加鎖、不等待;
  4. 若滿足,重新發起當前讀,加鎖並執行更新。

優勢:大幅減少 UPDATE 語句的行鎖衝突,對於大量不符合條件的記錄可提前放鎖,提升併發效能。RR 下 UPDATE 直接使用當前讀,遇鎖必須等待。

四、選型建議

  • 優先考慮 RC:高併發寫入場景、無嚴格可重複讀業務需求、使用 ROW 格式 Binlog 的現代架構。
  • 堅持 RR:業務強依賴可重複讀語義、歷史系統使用 Statement/Mixed Binlog、需利用 Gap Lock 隱式防幻讀。
  • 避免 SERIALIZABLE:除非極少數嚴格串行化需求,否則效能損耗過大。

五、總結

MySQL RC 與 RR 的差異本質上是鎖策略激進度與一致性視圖生命週期的權衡。RC 通過釋放無效鎖、半一致性讀優化更新併發,適合現代高吞吐系統;RR 通過統一 ReadView 與 Gap Lock 提供更強一致性保證,適合傳統事務密集型應用。理解這些機制差異,才能根據業務特性做出最優架構決策。

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