Mysql REPEATABLE-READ 可重复读事务隔离级别 MVCC下的幻读问题验证

我们知道在RR可重复读事务隔离级别下,是存在幻读问题的。但是在《高性能Mysql》中看到说mysql通过MVCC(多版本并发控制)解决了幻读问题的。所以就查了下资料,决定通过实践来验证一下这个问题。

实践是检验真理的唯一标准!这里先说结论:Mysql在可重复读事务隔离级别下,很大程度上避免了幻读,但某些场景下仍然是存在幻读问题的;可以通过MVCC或记录锁+间隙锁解决幻读问题。

验证过程:

  • 先查看下当前数据库的事务隔离级别,确认为REPEATABLE-READ级别。

  • 创建测试表
CREATE TABLE `test` (
  `id` int(8) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  • 打开两个连接窗口,开启两个事务进行测试

我们先插入一条数据: insert test(name) values('aaa');

场景1:

事务1先执行一次查询,返回1条数据;

然后开启事务2,执行 insert test(name) values('aaa'); commit 提交事务2;

事务1再次查询,是查询不到事务2新增的数据的。

结论:该场景下没有产生幻读(快照读,通过MVCC方式解决了幻读)。

场景2:

​接场景1(上图),在事务1中执行

update test set name='ccc' where name='aaa';

奇怪的情况出现了,可以看到前面查询时表里只有一条数据,但是执行update时却更新了两条数据,再次查询,查询到两条数据。

结论:该场景下出现幻读。

可以使用当前读(select for update)来避免这种幻读现象(当前读,通过记录锁+间隙锁的方式解决幻读);

或者在表中增加version字段,在select的where条件中手动控制version来避免幻读。

总结:

  • 场景1 insert的场景下,mysql通过MVCC的方式进行快照读,实现读已提交和可重复读。不会出现幻读情况。快照读,通过MVCC方式解决了幻读。
  • 但是在场景2 update的场景下,是会出现幻读的。可以使用当前读(select for update)来避免这种幻读现象(当前读,通过记录锁+间隙锁的方式解决幻读);或者在表中增加version字段,在where条件中手动控制version来避免幻读。

参考:

https://www.jianshu.com/p/cef49aeff36b

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值