MySql Read Commit 和 Repeatable Read非阻塞读实现原理

读提交和可重复读

Read Commit

读提交,事务可以读取已经提交的数据。
存在的问题:事务前后读取不一致。

Repeatable Read

可重复读,事务前后读取数据是一致的。
存在的问题:无法处理插入或者删除的数据。

MySql如何实现读提交和可重复读的?

innodb的聚簇索引中有2个隐藏字段,叫做trx_id (transaction id),和roll_pointer
trx_id描述一个事务编号,roll_pointer指向当前数据行的上一个历史版本,对于insert而言不存在历史版本
同时存在一个ReadView对象,里面有个队列描述当前正在处理的事务id。当有事务读取时,会先判断读取的行是否在这个队列中,如果存在就不会读取,会根据roll_pointer读取上一个版本的数据。
例:当事务id为100 的事务在修改id为1的行时,ReadView中队列会有[100]在里面,这时另一个事务读取id 为1 的数据行会首先发现trx_id 100的 小明2号 数据,随后会和ReadView的队列元素比较,发现存在,则随着roll_pointer去查询trx_id为60的数据行 小明1 ,发现60 不在队列中,于是读取值为小明1。

在这里插入图片描述

Read Commit的问题复现:

以上图为例,当事务trx_id 为 100 的事务修改 小明1 -> 小明2 时,此时未提交,于是另一个事务B在读取时会读取到 小明1,然后trx_id 为100的事务提交,这时刚才B又读了一遍,发现值变成 小明2。

Repeatable Read 复现 Read Commit

当事务trx_id 为 100 的事务修改 小明1 -> 小明2 时,此时未提交,于是另一个事务B在读取时会读取到 小明1,然后trx_id 为100的事务提交,这时刚才B又读了一遍,值还是 小明1。

导致差异的原理

Read Commit在查询时每次会生成新的ReadView,而Repeatable Read 则只会在第一次查询时生成ReadView,随后复用。
这导致Read Commit 每次查询时那个队列总是空的,就导致会读取到刚更新的数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值