mysql delete 幻读_【MySQL】聊一聊MySQL的幻读

本文探讨了MySQL中的幻读现象,包括快照读和当前读的区别。在RR隔离级别下,MySQL通过MVCC解决快照读的幻读,但当前读仍可能出现幻读。通过对Record Lock、Gap Lock和Next-Key Lock的分析,阐述了MySQL如何尝试缓解幻读问题,但是否完全解决幻读在不同认知中有不同看法。
摘要由CSDN通过智能技术生成

问题:

什么是幻读?

MySQL解决幻读了么?

幻读场景

场景一

7ad3e5fa899a524daf98ea8fe813b3c9.png

现象:事务A明明查出来没有数据ID为3的数据,但是插入的时候却报了主键冲突的问题,出现幻读的场景

场景二

8b25bf054f65b7ba4ee2c9b522bef040.png

事务A在更新name为cc的数据之前明明查出来只有一条匹配的,但是更新结果却对两条数据产生了影响,出现了幻读的场景。

当前读和快照读

如果只看上面的两种场景的话其实我们可以下结论说MySQL在RR级别下没有解决幻读的问题,但是网上关于幻读的讨论一大堆,而且官方也没有给出一个明确的定性,到底是什么原因呢?这时候就要引出MySQL的当前读与快照读

快照读

在RR级别下,通过MVCC机制,可以让数据变得可重复读,而MVCC实现原理就是在开启事务后的第一次select操作的同时创建一份快照,接下来再执行select操作就是从快照中读取的。

注意:

第一次select的时候才会创建快照,你可以测试在开启事务A之后,先不执行select操作,这时候让事务B插入一条数据,接着事务A再执行select的话会查出来事务B插入的数据。

快照读针对的是select操作,从上面可以看到我们在事务A的最后一步select的话读取到的是快照中的数据,但是update,delete,insert读取到的却不是

快照读虽然解决了可重复读,但是他可能让读出来的数据不是最新的数据,而是历史数据

当前读

MySQL对于update、insert、delete使用的都是当前读的模式,再执行这几个操作的时候读取到的都是当前最新的数据。别的事务提交的数据也可以查到,甚至别的数据未提交的数据也可以查到,你可以测试下在事务A插入一个id为10的数据但是不提交,这时候如果事务B同样插入一个数据为10的数据的话就会阻塞,你可以认为加了一个排他锁,你也可以站在另外一个角度认为他查询到了其他的事务操作的数据。

MySQL三种行锁

Record Lock:对单个行记录进行加锁

Gap Lock:间隙锁,对一个区间范围加锁,但不包含数据本身,所以叫做间隙,而GAP锁提出的原因就是为了解决幻读问题

Next-Key Lock:他是第一种和第二种的合体,这样就可以在锁住范围的同时锁住本身,对于行的查询,都是采用该方法,主要目的是解决幻读的问题。

结论

再了解了上面的问题以后我们再来看看为什么有的人认为MySQL在RR级别下解决了幻读,有的认为没有解决。

我认为这是对幻读的定位、认知不同。

在认为解决的人看来。幻读不能把快照读和当前读混起来操作,这是两种使用方式。幻读应该是在快照读或当前读本身的场景下,两次读取结果一致,而MySQL在快照读的情况下通过MVCC已经解决了,在当前读的情况MySQL通过next-key来解决了。

在认为没有解决的人看来。幻读应该不关心快照读还是当前读,只要第二次读(这个读比较广泛)读出了第一次读没有的数据就叫幻读,在这种定义下,我们可以从上面的两种场景看出,MySQL没有解决。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值