动态

详情 返回 返回

MySQL隔離級別:大廠為何偏愛RC? - 动态 详情

引言

​ 在剛畢業的時候,初入某家互聯網金融公司,作為杭州的某中廠,我看到其數據庫的事務隔離級別為 RR,所以很長的一段時間內,我都認為,數據庫的隔離級別就應該是 RR。直到後來入職杭州的某電商大廠,我才發現其實在大廠往往會將這個默認的數據庫級別更改為 RC,那麼為什麼會做出這種選擇呢?

1. 理解隔離級別:RR 與 RC 的核心差異

​ 當數據庫上存在多個事務一起執行的時候,就有可能出現髒讀、不可重複讀、幻讀的問題,為了解決這些問題,就有了隔離級別的概念

​ SQL 的標準事務隔離級別包括:讀未提交、讀已提交(RC)、可重複讀(RR)、串行化;隔離級別的“嚴格性”依次遞升,隔離的越嚴實,意味着效率就越低,故我們需要根據當前的業務場景去判斷什麼樣的隔離級別適合我們的業務。

​ 我們核心關注 RC 和 RR 這兩個級別,他們的核心差異在哪裏呢?

讀已提交 (RC):一個事務只能讀取到其他事務已經提交的數據。它解決了“髒讀”問題,但無法避免“不可重複讀”和“幻讀”。

可重複讀 (RR):一個事務在執行過程中看到的數據,與該事務啓動時看到的數據是一致的。換言之,即使其他事務修改並提交了數據,該事務也看不到這些變更。它解決了“髒讀”和“不可重複讀”,但在MySQL的InnoDB引擎中,通過“Next-Key Lock”機制部分解決了幻讀

經典八股,務必熟背

髒讀:一個事務讀取到了另一個尚未提交的事務的修改數據

不可重複讀:在同一個事務內,兩次讀取同一條數據,結果不一致(因為被其他已提交事務修改了)。

幻讀:在同一個事務內,兩次執行相同的查詢,返回的記錄集合不一致(因為被其他已提交事務新增或刪除了數據)。

2. MySQL 的加鎖機制:RR 如何阻止幻讀

​ 在大多數的情況下,RC 級別在只會加行鎖,所以我們暫不展開説明

​ RR 級別我們上文説了,會通過 Next-Key Lock 進行幻讀機制的保證,是藥三分毒,是鎖就會對性能有所影響

​ 我們先回顧一下 MySQL 的加鎖規則(借鑑丁奇的 《MySQL45 講》)

​ 包含了兩個“原則”、兩個“優化”和一個“bug”。

​ 原則1:加鎖的基本單位是next-key lock。next-key lock是前開後閉區間。

​ 原則2:查找過程中訪問到的對象才會加鎖。

​ 優化1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock退化為行鎖。

​ 優化2:索引上的等值查詢,向右遍歷時且最後一個值不滿足等值條件的時候,next-key lock退化為間隙鎖。

一個bug:唯一索引上的範圍查詢會訪問到不滿足條件的第一個值為止。

​ RR 之所以可以避免幻讀,就是藉助了 Next_Lock,Next-Key Lock可以理解為是記錄鎖(鎖住某條具體的索引記錄)和間隙鎖(鎖住記錄之間的間隔)的組合。

​ 例如,執行 SELECT * FROM users WHERE age BETWEEN 20 AND 30 FOR UPDATE。在RR級別下,這條語句不僅會鎖住年齡在20到30歲之間的現有用户記錄,還會鎖住這個年齡區間所有的“間隙”,阻止任何新用户(比如年齡為25歲)的插入。這確實有效地防止了幻讀,但代價是顯著降低了數據庫的寫入併發能力。

​ 而在RC級別下,通常只會對現有的記錄加鎖,不會使用間隙鎖,因此其他事務插入新記錄的操作基本不受影響,併發性自然更高

3. 大廠為何偏愛 RC

​ 大廠選擇RC級別,並非對數據一致性要求低,而是基於高併發場景下的務實權衡。在許多業務邏輯中,幻讀的實際影響被高估了。例如電商扣減庫存的場景:

UPDATE stock SET count = count - 1 WHERE product_id = 'xxx' AND count > 0;

​ 該UPDATE語句本身是原子的,即使在兩次查詢之間發生幻讀(新增了庫存記錄),也不會影響扣減操作的正確性。在這種情況下,放棄RR的“強一致性”保障,換取更高的併發性能,是更具性價比的選擇。

此外,RC級別還有以下優勢:

  • 鎖競爭更少:避免間隙鎖,減少死鎖概率,提升系統穩定性
  • 性能更優:降低鎖開銷,提高事務處理吞吐量
  • 問題更易排查:鎖行為更簡單,線上問題定位效率更高

​ 因此,大廠在業務允許的範圍內,傾向於使用RC級別,並通過應用層邏輯(如樂觀鎖、狀態機、流水錶等)彌補RC在一致性上的不足,實現性能與安全的平衡。

user avatar mannayang 头像 king_wenzhinan 头像 xuxueli 头像 u_16769727 头像 lenglingx 头像 u_15702012 头像 lvlaotou 头像 ahahan 头像 lenve 头像 huangxunhui 头像 aipaobudezuoyeben 头像 chaochenyinshi 头像
点赞 65 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.