MySQL(五)—MVCC解决可重复读的幻读了吗?

一、概览

MVCC在一定程度可以避免幻读,但是不能完全解决幻读

二、举例说明什么是幻读,重现幻读现象

什么是幻读

把读写事务出现的三个问题再回顾一下

脏读:事务A读取到事务B未提交的数据,此时为脏读。
不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。
幻读:事务A以同种条件先后查询数据库,两次查询结果的条数不同,这种现象称为幻读。

脏读和不可重复读的区别:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据
不可重复读与幻读的区别:前者是数据变了,后者是数据的行数变了。

举例说明幻读

首先设置事务A为读已提交隔离级别。
在这里插入图片描述

三、举例说明可以一定程度上解决幻读

现在设置事务A的隔离级别为可重复读
在这里插入图片描述
前面我们将MVCC实现可重复读原理中提到,读分为快照读和当前读(或者叫加锁读)。当前读就是写操作需要先读取最新的数据然后再写,写的过程是加锁的。

列举下快照读和当前读的操作。

1. 快照读(snapshot read)
简单的select操作(不包括 select ... lock in share mode, select ... for update)
    
2.当前读(current read)
select ... lock in share mode
select ... for update
insert
update
delete

因此在可重复读的时候,读的是快照中的数据,即ReadView中的数据,也就是历史数据。

那么为什么读已提交会产生幻读现象呢?

因为在RC(读已提交)隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR(可重复读)隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。

四、举例说明没有完全解决幻读

RR虽然避免了幻读问题,但是毕竟不是Serializable,不能保证完全的隔离

如果在事务中第一次读取采用快照读,第二次读取采用当前读,则如果在两次读取之间数据发生了变化,两次读取到的结果不一样,因为加锁读时不会采用MVCC。如下例子

在这里插入图片描述

所以从以上实验中就可以得出MVCC在一定程度可以避免幻读,但是不能完全解决幻读

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿成长轨迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值