点击上方“业余草”,选择“置顶公众号”
第一时间获取技术干货和业界资讯!
昨天,微信群里一位网友,发了一个可重复读和幻读的测试代码,问什么?由于半个小时的时间,我要赶一篇明天的文章出来,就没细看。明天抽时间在具体的看看,今天我就着这个话题,先来说一说不可重复读和幻读的区别吧!
首先,mysql 幻读并非是 "一个事务内进行两次相同操作居然得到了不一样的结果",因为它根本不可能发生在使用了 read view / MVCC 的 RR 隔离级别下,这种幻读的定义更适合给 Oracle,Oracle 的事务隔离只有两级,RC 和 Serializable。然后还有很多人说不可重复读是针对某条记录的,幻读是针对记录集合的,这略微牵强。。。
有人说:不可重复读的重点是针对 update, delete。而幻读的重点针对的是 insert。这么说是对的吗?
网上有很多文章这样认为。其实也并没有什么大错!
产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记录之间的“间隙”。因此,为了解决幻读问题,InnoDB 只好引入新的锁,也就是间隙锁 (Gap Lock)。
顾名思义,间隙锁,锁的就是两个值之间的空隙。
不可重复读的重点是针对 update, delete。而幻读的重点针对的是 insert。(可以参考MySQL官方文档对 Phantom Rows 的介绍)。
其实 REPEATABLE READ 就可以防止幻读, 《高性能MySQL》中也说了, REPEATABLE READ 理论是是不能防止幻读的, 但是由于该隔离级别还使用了MVCC, 可以做到非锁定一致性读取, 所以, 只要你真的确定你明白幻读的意思, 你在 REPEATABLE READ隔离级别下是模拟不出幻读效果的。
改天模拟一个场景出来!