MySQL InnoDB的Repeatable Read隔离级别就一定能避免不可重复读吗

在上一篇InnoDB可重复读隔离级别是如何实现的文章中,提到了快照读,MySQL通过MVCC中快照读的方式解决不可重复读问题,那么在RR级别下就一定能避免不可重复读吗,我们来一起看下。

快照读:
在RR隔离级别下,同一事务中后边所有这样的读读到的都是第一个这样读的快照,
或是被当前事务刷新过的快照,这样做到了可重复读。

需要注意这个被当前事务刷新过的快照,当事务中发生了当前读
(在默认隔离级别下,普通的select就是快照读,而insert、update、delete、select … lock In share mode、select … for update,特别是写操作,只能是当前读,否则会发生write skew问题。)
事务会刷新readView,也就是快照snapshot,那么可能会看到下面的现象。

1、第一次查询的时候codepoint = 97;
生成快照。

2、修改codepoint = codepoint + 1;
这个时候是当前读,在此基础上修改后刷新snapshot。

3、第二次查询的时候codepoint = 101;
上一步当前读读到的codepoint的值是被其它事务修改后的100。

mysql> SELECT * FROM char_encode WHERE glyph = 'a';
+-------+-----------+
| glyph | codepoint |
+-------+-----------+
| a     |        97 |
+-------+-----------+
1 row in set (0.03 sec)

mysql> UPDATE char_encode SET codepoint = codepoint + 1 WHERE glyph = 'a';
Query OK, 1 row affected (0.07 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM char_encode WHERE glyph = 'a';
+-------+-----------+
| glyph | codepoint |
+-------+-----------+
| a     |       101 |
+-------+-----------+
1 row in set (0.03 sec)

等等,怎么发生了不可重复读,这不违反可重复读隔离级别吗。。。
但是Who cares?毕竟官方都说了:

“This is not a bug but an intended and documented behavior.”

奈何本人没文化,去找百度翻译下:

这不是bug,而是刻意为之。

说明MySQL是允许这样的。

参考文章:

in355hz既然MySQL中InnoDB使用MVCC,为什么REPEATABLE-READ不能消除幻读?

猜你喜欢

转载自blog.csdn.net/qq_35549286/article/details/108537325
今日推荐