MySQL:Repeatable Read隔离级别是如何基于ReadView机制实现的

引入

  • 在MySQL中让多个事务并发运行的时候能够相互隔离,避免同时读写一条数据的时候有影响,是依托于undo log版本链和ReadView机制来实现的。
  • 基于ReadView机制可以实现RC隔离级别,就是每次查询的时候都生成一个ReadView,这样的话,只要你在这次查询之前由别的事务提交了,那么别的事务更新的数据,你是可以看到的。

那RR级别是如何实现的呢?

  • 需要明确的是,MySQL默认是RR(可重复读)级别,它避免了脏读、脏写、可重复读、幻读的问题。
  • RR级别下,你这个事务读一条数据,无论读多少次,都是一个值,别的事务修改数据之后哪怕提交了,你也是看不到人家修改的值的,这就避免了不可重复读的问题
  • 同时如果别的事务插入了一些数据,你也是读不到的,这样就可以避免幻读的问题

实现原理

如何解决不可重复读

  • 假设有一条数据是事务ID=5是一个事务插入的,同时此时有事务A和事务B同时在运行,事务A的ID是60,事务B的ID是70,如下图:

在这里插入图片描述

  • 这个时候,事务A发起了一个查询,它就是第一次查询就生成一个ReadView,此时ReadView里的creator_trx_id是60,min_trx_id是60,max_trx_id是71,m_ids是[60, 70],如下图:

在这里插入图片描述

  • 这个时候事务A基于这个ReadView去查这条数据,发现这条数据的trx_id为50,是小于ReadView里的min_trx_id的。说明它发起查询之前,早就有事务插入这条数据还提交了,所以此时可以查到这条原始值的。如下图:

在这里插入图片描述

  • 接着就是事务B此时更新了这条数据的值为值B,此时会修改trx_id为70,同时生成一个undo log,而且事务B还提交了,也就是事务B结束了。如下图:

在这里插入图片描述

  • 那此时ReadView中的m_ids还会是60和70吗?
  • 必然是的,因为ReadView一旦生成了就不会改变了,这个时候虽然事务B已经结束了,但是事务A的ReadView里,还是会有60和70两个事务id。
  • 它的意思是,在事务A开启查询的时候,事务B当时是在运行的。
  • 那么此时如果事务A再去查询这条数据的值,它会发现此时数据的trx_id是70了,70这时在ReadView的min_trx_id和max_trx_id的范围区间的,同时还在m_ids列表中。这说明什么呢?
  • 说明事务A开启查询的时候,id为70的这个事务B还是在运行的,然后由这个事务B更新了这条数据,所以此时事务A是不能查询到事务B更新的这个值的,因此这个时候继续顺着指针往历史版本链条上去找,如下图。

在这里插入图片描述

  • 接着事务A顺着指针找到下面一条数据,trx_id为50,是小于ReadView的min_trx_id的,说明在它开启查询之前,就已经提交了这个事务了,所以事务A是可以查询到这个值的,此时事务A查到的是原始值,如下图。

在这里插入图片描述
从上面可以看到,它避免了不可重复读的问题。

  • 事务A多次读同一个数据,每次读到的都是一样的值,除非是它自己修改了值,否则读到的一直会是一样的值
  • 不管别的事务如何修改数据,事务A的ReadView时钟是不变的,它基于这个ReadView时钟看到的值都是一样的

如何解决幻读问题

  • 假设现在事务A先用select * from x where id>10来查询,此时可能查到的就是一条数据,而且读到的一定是是这条数据的原始值的那个版本

在这里插入图片描述

  • 现在有一个事务C插入了一条数据,然后提交了,此时如下图所示:
    在这里插入图片描述

  • 接着,此时事务A再次查询,此时会发现符合条件的有2条数据,一条是原始值那个数据,一条是事务C插入的那条数据,但是事务C插入的那条数据的trx_id是80,这个80是大于自己的ReadView的max_trx_id的,说明是自己发起查询之后,这个事务才启动的,所以此时这条数据是不能查询的。

  • 因此事务A本次查询,还是只能查到原始值一条数据。如下图:

在这里插入图片描述
可以看到,事务A根本不会发生幻读,它根据条件范围查询的时候,每次读到的数据但是一样的,不会读到人家插入的数据,这都是基于ReadView机制实现的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值