首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

InnoDB 事務隔離級別深度解析:REPEATABLE READ 無幻讀實測與 MVCC 實現原理

     編輯:MySQL 資料庫相關知識

四大隔離級別對照

InnoDB REPEATABLE READ 獨特行為:無幻讀

標準 RR 允許幻讀,但 InnoDB 通過 Next-Key Locking (記錄鎖 + 間隙鎖) 實現無幻讀,等同 SERIALIZABLE 效果但併發度更高。

實測驗證過程

-- 環境:MySQL 5.0.37, 兩個 Session,隔離級別 RR, autocommit=0

-- Session 1
CREATE TABLE test (i INT) ENGINE=InnoDB;
INSERT INTO test VALUES (1);
-- 未提交

-- Session 2
SELECT * FROM test;  -- Empty set (無髒讀)

-- Session 1
COMMIT;

-- Session 2
SELECT * FROM test;  -- Empty set (無幻讀!標準 RR 會看到新行)

-- Session 2
COMMIT;  -- 或新事務
SELECT * FROM test;  -- 現在看到 (1)

MVCC 實現核心

  • Undo Log 版本鏈:每行記錄隱藏 DB_TRX_ID (事務 ID)、DB_ROLL_PTR (回滾指針)
  • Read View:事務啟動時建立,記錄當前活躍事務 ID 列表
  • 可見性判斷:
    1. 目標版本 trx_id < read_view.min_trx_id → 可見(已提交)
    2. 目標版本 trx_id > read_view.max_trx_id → 不可見(未來事務)
    3. 中間:檢查是否在活躍列表 → 在則不可見,不在則可見
  • RR vs RC 差異:RR 事務啟動建立 Read View,全程複用;RC 每條 SELECT 重新建立

鎖與隔離級別關係

級別髒讀不可重複讀幻讀InnoDB 預設
READ UNCOMMITTEDYYY
READ COMMITTEDNYYOracle/PostgreSQL 預設
REPEATABLE READNNY (標準)InnoDB 預設
SERIALIZABLENNN

修改隔離級別

-- 全域 (需重連生效)
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 或 my.cnf: transaction-isolation = READ-COMMITTED

-- 會話級 (立即生效)
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 查看
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;

選型建議

  • RR (預設):大多數業務,無幻讀保證,併發較好
  • RC:需見最新提交數據、減少間隙鎖死鎖、Statement-based Replication 相容
  • SERIALIZABLE:極少用,嚴格串行化,效能差
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作READ COMMITTEDREPEATABLE READ
SELECT (普通)無鎖 (MVCC)無鎖 (MVCC)
SELECT ... LOCK IN SHARE MODE記錄鎖 (S)記錄鎖 + 間隙鎖 (Next-Key)
SELECT ... FOR UPDATE記錄鎖 (X)記錄鎖 + 間隙鎖 (Next-Key)
UPDATE/DELETE (有索引)記錄鎖Next-Key Lock
UPDATE/DELETE (無索引)全表記錄鎖全表 Next-Key Lock