MySQL REPEATABLE READ真的不会出现幻读么

MySQL REPEATABLE READ真的不会出现幻读么

众所周知,MySQL在事务隔离级别REPEATABLE READ的情况下,是可以防止幻读现象的产生的,这点不同于SQL标准。但是,MySQL真的就做的很完美么?让我们来看一个例子,我们会发现MySQLREPEATABLE READ的隔离级别下,竟然也出现了幻读现象。依旧以mysqld 8.0.20-debug为例子。

1 表

表的schema为:

drop table t;
create table t(
    a int PRIMARY KEY,
    b int
);

insert into t values(1,1),(2,2),(4,4),(5,5);

2 例子

两个session的操作顺序如下:

时间线 session A session B
1 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
begin;
select * from t;
2 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
begin;
insert into t values(3,3);
3 select * from t;
4 commit;
5 select * from t;
/*发生了更新,导致下面的select语句看到了session b提交的结果*/
update t set b = b * 10;
select * from t;

在sessionA中,当我们执行update t set b = b * 10;之后,在执行select * from t查询语句,得到的结果如下:

+---+------+
| a | b    |
+---+------+
| 1 |   10 |
| 2 |   20 |
| 3 |   30 |
| 4 |   40 |
| 5 |   50 |
+---+------+

可以看到,a = 3这一行的数据也查询到了,其实和直观猜测的一样,是因为update语句的原因,才导致session A看到了session B提交的结果,即便是REPEATABLE READ隔离级别下也会出现这样的结果。这个是什么原因呢?其实这个问题早就有人提出来了,并且也给出了答案,详情见淘宝的官方博客,这片文章里有详细的介绍,其实并不是一个bug。

原文地址:https://www.cnblogs.com/seancheer/p/15186260.html