mysql 快照读 幻读_innodb当前读 与 快照读 and rr级别是否真正避免了幻读

MySQL的InnoDB在RR隔离级别下,通过MVCC和next-key技术处理快照读和当前读。MVCC用于快照读,提供历史数据一致性,但可能产生幻读。next-key锁用于当前读,确保数据实时性,完全避免幻读。RR级别并未完全解决幻读,需要手动加锁调整为当前读才能完全避免。幻读发生于快照读特定场景,可通过加锁读取最新数据。
摘要由CSDN通过智能技术生成

快照读历史数据-mvcc

innodb的默认事务隔离级别是rr(可重复读)。它的实现技术是mvcc。基于版本的控制协议。该技术不仅可以保证innodb的可重复读,而且可以防止幻读。(这也就是是此前以rr隔离级别实践时,不仅可以防止可重复读,也防止了欢度)但是它防止的是快照读,也就是读取的数据虽然是一致的,但是数据是历史数据。(http://blog.sina.com.cn/s/blog_499740cb0100ugs7.html这个帖子里面就有一个实例)

当前读最新数据-next key

如何做到保证数据是一致的(可重复、幻)(也就是一个事务,其内部读取对应某一个数据的时候,数据都是一样的),同时读取的数据是最新的数据。innodb提供了一个间隙锁的技术,即next-key,也就是结合grap锁与行锁,达到最终目的。当使用索引进行插入(或select,update等)的时候,innodb会将当前的节点(record_lock)和上一个节点(gap lock)加锁?。这样当进行select的时候,就不允许加x锁。那么在进行该事务的时候,读取的就是最新的数据。(同样的,反过来看,当select in share mode时加next-key锁,视查询索引是否唯一而定一片数据的insert和update阻塞),当两个当前读在一个事务中,别的update insert delete就无法打断,也就不会出现重复读和幻读。

实现:

1. 快照读(snapshot read)

简单的select操作(不包括 select ... lock in share mode, select ... for update)

2.当前读(current read)

select ... lock in share mode

select ... for update

insert

update

delete

在RR级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。(u  无锁读   rc mvcc rr mvcc s 自动升级为当前读)

所以从上面的显示来看,如果需要实时显示数据,还是需要通过手动加锁来实现。这个时候会使用next-key技术来实现。

总结:在mysql中,提供了两种事务隔离技术,第一个是mvcc,第二个是next-key技术。这个在使用不同的语句的时候可以动态选择。不加lock inshare mode之类的快照读就使用mvcc。否则 当前读使用next-key。mvcc的优势是不加锁,并发性高。缺点是不是实时数据。next-key的优势是获取实时数据,但是需要加锁。

另外,重要:

在rr级别下,mvcc完全解决了重复读,但并不能真正的完全避免幻读,只是在部分场景下利用历史数据规避了幻读

对于快照读,mysql使用mvcc利用历史数据部分避免了幻读(在某些场景看上去规避了幻读)

要完全避免,需要手动加锁将快照读调整为当前读(mysql不会自动加锁),然后mysql使用next-key完全避免了幻读,比如rr下,锁1(0,2,3,4),另一个线程的insert 3即被阻塞,在rc下,另一个线程仍然可以大摇大摆的插入,如本线程再次查询比如count,则会不一致

参考:https://www.cnblogs.com/cat-and-water/p/6429268.html  MySQL的InnoDB的幻读问题

同时需要注意几点:

1.事务的快照时间点是以第一个select来确认的。所以即便事务先开始。但是select在后面的事务的update之类的语句后进行,那么它是可以获取后面的事务的对应的数据。

2.mysql中数据的存放还是会通过版本记录一系列的历史数据,这样,可以根据版本查找数据。

// 一段极关键的尝试

http://blog.sin

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值