前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Innodb RR隔离级别下到底能否避免幻读

Innodb RR隔离级别下到底能否避免幻读

作者头像
用户5397975
发布2021-09-09 11:43:53
1.5K1
发布2021-09-09 11:43:53
举报
文章被收录于专栏:咖啡拿铁咖啡拿铁

背景

这个事情要回溯到曾经背八股文的时候了,想必大家在背八股文的时候对于事务隔离级别都已经背得滚瓜烂熟了,一般在说隔离级别的时候,都顺带会提到mysql的innodb的RR隔离级别,由于他与众不同的实现方式,通常会有下面的一些描述:

在我的脑海里面一直就记着,mysql的Innodb在RR隔离级别下就能避免幻读(曾经面试的时候也这样回答过),但是直到有一天群里的同学抛出了一个问题,

,我的第一反应也是

怎么定义幻读?

其实对于这个争论,很多点在于什么才叫做幻读?先来一个幻读的通俗的定义,对于相同的区间查询,插入和删除操作使得对相同的区间查询操作返回不同的结果。

在Innodb的RR隔离级别下,比如我们对一个表进行(id>1 and i < 100)的删除操作,另外一个事务这个时候插入一条id=50的数据,如果插入成功的话就会导致我们第一个事务出现幻觉,所以在inndodb中使用了next-key lock算法,也就是加了间隙锁,从而阻止插入意向锁。

接下来我们再看一下MYSQL官方定义的幻读:

翻译过来其实就是:当同一个查询在不同的时间产生不同的集合时,就会发生所谓的幻读问题。例如,如果一个SELECT执行了两次,但是第二次返回了第一次没有返回的行,那么该行就是一个“幻像”行。

这个定义和我们开始那个定义有什么区别吗?看起来区别不大,但是细细的品味第一个定义限制了插入和删除。在MYSQL的官方定义下,用了两次查询,并没有定义另外一个事务做了什么,以及两次查询之间发生了什么,所以出现了这样的一个情况:

上面有两个事务,事务B发生了幻读的现象,为什么说这里是幻读的现象呢?因为按照MYSQL的定义两次查询返回不同集合,事务B的确是发生了幻读现象。

为什么会出现这个情况呢?这个主要还是因为在innodb下所有的读都是快照读,如果我们在事务中对这个数据加锁,那么就变成了当前读,所以就能读取到事务A写的数据了。这种情况在一些文献中也被叫做: write skew style phantom

RR级别如何解决幻读?

其实我们细细分析,我们上面那个情况是怎么解决的幻读,是依靠next-key lock,而我们第二个案例虽然在事务中但是却没有使用next-key lock,如果我们真的对幻读有很多要求的话,那么我们在查询的时候直接加上select ... for update 加上锁,这样可以直接让我们走当前读,从而避免幻读的出现。

最后

这篇文章营养价值不高,主要是用来纠正大家一些观念,有时候八股文盲目去背没有细细思考,可能就会导致认知上的错误。最后总结一下,在RR隔离级别下只要不出现快照读和当前读的切换,其实就能保证不会出现幻读

如果大家觉得这篇文章对你有帮助,你的关注和转发是对我最大的支持,O(∩_∩)O:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 咖啡拿铁 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 怎么定义幻读?
  • RR级别如何解决幻读?
  • 最后
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档