Mysql的Repeatable Read如何解决幻读

幻读的现象是在数据库事务中,在两次同样的查询条件下,得不一样的结果。发生这个现象的主要原因是,在两次查询之间,其他事务插入了新的数据,原来的事务没有对新增的数据进行过滤或者限制插入,导致第二次与第一次查询结果不一致。

所以要解决幻读有两种方式,第一种是在查询时过滤新增的数据;第二种是加锁,不让新数据插入成功。

第一种方式是基于MVCC实现,MVCC模式下每条数据都会带上事务ID、之前版本数据的引用(Undo Log),所以当前事务只要过滤掉比自己事务晚提交的记录,就能避免幻读。具体实现是在事务中第一次select时会构建ReadView,包含最小活跃事务ID、活跃事务ID列表、最大的事务ID、当前事务ID。通过这几个事务ID,就能判断出某条新增的记录是早于当前事务还是晚于。具体规则如下:

1. 小于最小活跃事务ID的都是已提交事务,当前事务可见

2. 大于最大的事务ID的,一定比当前事务晚,当前事务不可见

3. 在最小和最大事务ID之间的,已提交的事务的修改可见,未提交的事务的修改不可见

第二种方式是基于Next-key Lock(行锁+间隙锁)实现,如果在事务中使用了当前读,即读的时候使用了for update、lock on share mode等,会读到最新提交的数据,此时避免幻读就要通过对记录和记录间隙加锁,阻止其他事务修改当前记录或在记录之间插入新数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李昂的数字之旅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值