幻读的例子:
例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读可能发生在update,delete操作中,而幻读发生在insert操作中。
注意,幻读出现的场景
1)事务的隔离级别为可重复读,且是当前读
2)幻读仅专指新插入的行,在范围查询中,后一次查询出现了新的数据行。
标准的事务隔离级别中,可重复读只能解决 不可重复读 的问题,无法解决 幻读 的问题。
但是在MySQL的InnoDB引擎中,通过间隙锁(gap lock)+行锁组成的next-key lock,在可重复读级别下解决了幻读的问题。
具体可以参考我的这篇文章。阿丸:前阿里数据库专家总结的MySQL里的各种锁(下篇)zhuanlan.zhihu.com