Innodb 中 RR 隔離級別能否防止幻讀?


問題引出

我之前的一篇博客 數據庫並發不一致分析 有提到過事務隔離級別以及相應加鎖方式、能夠解決的並發問題。

標准情況下,在 RR(Repeatable Read) 隔離級別下能解決不可重復讀(當行修改)的問題,但是不能解決幻讀的問題。

而之前有看過一篇 mysql 加鎖的文章 MySQL 加鎖處理分析,里面有提到一點:

對於Innodb,Repeatable Read (RR) 針對當前讀,RR隔離級別保證對讀取到的記錄加鎖 (記錄鎖),同時保證對讀取的范圍加鎖,新的滿足查詢條件的記錄不能夠插入 (間隙鎖),不存在幻讀現象。

那么問題來了,到底 Innodb 中 RR 隔離級別是否能解決幻讀呢?

在 MySQL 加鎖處理分析這篇文章下面的評論中,有這樣的一個交流:

ontheway
弱弱地問一句,我看的書里面都說的是RR隔離級別不允許臟讀和不可重復讀,但是可以幻讀,怎么和作者說的不一樣呢?

hedengcheng(作者)
你說的沒錯,因此我在文章一開始,就強調了這一點。mysql innodb引擎的實現,跟標准有所不同。

求證官方文檔

MySQL Innodb 引擎的實現,跟標准有所不同,針對這個問題,我表示懷疑,於是查看 mysql 官方文檔關於 RR的解釋,里面有這么一段話:

For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key locks to block insertions by other sessions into the gaps covered by the range.

大致意思就是,在 RR 級別下,如果查詢條件能使用上唯一索引,或者是一個唯一的查詢條件,那么僅加行鎖,如果是一個范圍查詢,那么就會給這個范圍加上 gap 鎖或者 next-key鎖 (行鎖+gap鎖)。

從這句話的理解來看,和文章里的解釋一樣,由於 RR 級別對於范圍會加 GAP 鎖,這個和 sql 的標准是有一些差異的。

其他解釋

后面又發現了一篇文章 Understanding InnoDB transaction isolation levels,文章中又提到:

This isolation level is the default for InnoDB. Although this isolation level solves the problem of non-repeatable read, but there is another possible problem phantom reads.

大概意思是,RR 能解決不可重復讀的問題,但仍可能發生幻讀,懷疑作者並不了解 Innodb 的特殊實現,評論中也有提到:

Do you mean 'write skew' instead of 'phantom reads'? The 'repeatable read' in SQL standard allows 'phantom reads', however, since InnoDB uses next-key locking this anomaly does not exist in this level. Looks like it's equivalent to 'snapshot isolation' in Postgres and Oracle.

再來看一篇文章 MySQL的InnoDB的幻讀問題,這里面提供了一些例子,還沒來得及分析,但最后的結論是:

MySQL InnoDB的可重復讀並不保證避免幻讀,需要應用使用加鎖讀來保證。而這個加鎖度使用到的機制就是next-key locks。

最終結論

Innodb 的 RR 隔離界別對范圍會加上 GAP,理論上不會存在幻讀,但是是否有例外呢,這個還需要進一步求證。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM