Mysql的事务隔离级别以及脏读,可重复读,幻读,MVCC等

Mysql的事务隔离级别以及脏读,可重复读,幻读,MVCC等

虽然这个题目在网上已经被写烂了,但在看各种博客和自己验证的时候还是看到很多不同的现象。所以还是用自己的话总结下吧。

假如有问题,请指出来,谢谢!

脏读

一个事务读取到另外一个事务的"脏"数据。比如两个事务操作同样的数据的时候,事务A修改了了某行(假如仅操作一行)数据,事务B读取到了(在特定的事务隔离级别才可以发生)修改后的值,此时事务A再回滚操作,那么事务B读取的值和该行数据真正的值就不一样了,就称之为"脏"数据。

不可重复读

一个事务里面,两次相同的查询,读取到的数据不一致。比如事务B先读取到了某行数据,事务A此时修改了该行记录并提交。事务B再次用相同的查询来读取该行记录的时候,会读取到事务A修改后的值,和第一次查询的结果不一样。

幻读

相同的查询语句,在事务中第二次读数据的时候,读到预期外的记录。

这里在网上看到很多说法,有的说事务隔离级别为RR(可重复读)的时候,会出现幻读,有的说RR是可以解决幻读的,下面我用一个例子,分别模拟RR模式下,不出现幻读和出现幻读的两种场景。

下面的例子,处于Mysql innodb引擎下面的默认隔离级别RR。

在这里插入图片描述我们可以看到,在RR级别,先是避免了幻读,然后又发生了幻读,下面简单说明下:

  1. 在数据库的隔离级别的协议中,RR级别是可以避免提交读(即可做到重复读),但是无法避免幻读的。Mysql数据库通过MVCC(多版本并发控制)实现可重复读的,后文会简单描述下MVCC,并且可以做到一定程度上避免幻读,MVCC是快照读,假如你在这个事务中不破坏这个快照读,让它升级为当前读,那么这个事务中,是能保证可重复读,且不发生幻读的。

  2. 当你在事务中把后面的读升级为当前读的时候,则可能会出现幻读,因为以及读取到了最新的数据了,那么其他事务的提交就可能会读取出来。

  • 快照读:

      mvcc模式下普通的select
    
  • 当前读:

      select ... lock in share mode (共享读锁)
    
      select ... for update (排它锁,下面同,这几种都会使当前事务读取到最新的数据,并阻塞其他事务,直到当前事务提交或者回滚。)
    
      update
    
      insert
    
      delete
    

总结:

当处于RR隔离级别下,由于Mysql使用了MVCC,是能部分避免幻读的,前提是你没有主动破坏MVCC给你带来的快照读。当然在RR模式下,我们可以手动来完全避免幻读,比如说第一次查询数据的时候,我们就使用select for update(不带where条件,锁整个表)直接给它来个排它锁,那其他事务想有insert操作也会被阻塞住。不过这和串行的事务隔离级别又有什么两样呢?

事务隔离级别

这个被说烂了,图也被上烂了,我还是再上下图,下图为Mysql的4种隔离级别,Oracle默认为RC,Mysql默认为RR。
在这里插入图片描述

MVCC

这里只针对上文中的例子,简单提一下为何mvcc如何实现可重复读和部分避免幻读。原理大概是这样,比较白话的描述出来,有问题请纠正。

  1. 每个db中维护当前事务版本,递增,每新开一个事务的时候,当前事务版本+1,并赋值给新开的这个事务。

  2. 每行记录默认加两个隐藏字段:

    1. 新增事务序号字段:表示该条记录是在哪个事务中产生的,把当前事务序号赋值给它。

    2. 删除事务序号字段:这个和上面的例子没有关系,先忽略。

  3. 在mvcc模式下,事务1中的第一次查询,会行成一个快照点,即意味着可以查询之前的版本的数据,而不用查询最新的数据。查询的时候,Innodb引擎会默认在查询语句后,带上 and trans_version <= curr_trans_version,即你怎么查,都是查询当前事务或者之前事务产生的数据,此时即使事务2新增了其他数据,或者修改了某些数据(update也会更新新增事务序号字段为当前事务版本),也不会被查询出来。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值