MySQL默认隔离级别是RR,但是为什么一些大厂会改成RC?

MySQL默认隔离级别是RR,但是为什么一些大厂会改成RC?为什么默认隔离级别是RR?可能大部分人都只知道MySQL的隔离级别有4个,分别是RU读未提交、RC读已提交、RR可重复读和Serializable可串行化,很少有人知道MySQL默认的隔离级别是RR,Oracle默认的隔离级别是RC。那就更少有人知道为什么MySQL默认的隔离级别是RR了。我也是刚刚工作之余看到了一篇文章,里面简单提了一下这个问题,我就四处找寻了一下答案,将自己所理解的记录下来,希望对大家有帮助。理解脏读、不可重复读、幻读脏读:某个事务对一份数据执行了更新操作,另一个事务在此时读


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

为什么默认隔离级别是RR?

可能大部分人都只知道MySQL的隔离级别有4个,分别是RU读未提交、RC读已提交、RR可重复读和Serializable可串行化,很少有人知道MySQL默认的隔离级别是RR,Oracle默认的隔离级别是RC。那就更少有人知道为什么MySQL默认的隔离级别是RR了。我也是刚刚工作之余看到了一篇文章,里面简单提了一下这个问题,我就四处找寻了一下答案,将自己所理解的记录下来,希望对大家有帮助。

理解脏读、不可重复读、幻读

脏读:某个事务对一份数据执行了更新操作,另一个事务在此时读取了同一份数据,由于某些原因,前一个事务又执行了RollBack回滚操作,则后一个事务所读取的数据就会是不正确的。我们称此时发生了脏读。也就是读取到了未提交事务的数据,发生在读取阶段。

不可重复读:在同一个事务的先后两次查询的结果数据不一致。可能是在两次查询之间另一个事务执行了更新的操作并已提交。当然大部分情况下这种情况是允许的,毕竟我们要以最新的数据为标准。

幻读:在同一个事务当中先后两次查询结果的总数不一致,例如前一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,前一个事务此时再执行一次查询操作,就会出现有几列数据是未查询出来的,但是如果此时前一个事务想要插入后一个事务插入的数据,就会报错(在前一个事务看来,我明明没有这些数据,怎么还插入不进去???就跟发生了幻觉一样)。发生在插入阶段。

MySQL默认RR隔离级别的原因

主要和MySQL主从复制相关,因为MySQL在主从复制过程中是通过binlog进行数据同步的,而MySQL早期只有statement这种binlog格式,这种格式下,binlog记录的是SQL语句的原文。所以在事务乱序的时候,就会导致备库在进行SQL回放之后,结果和主库不一致。

为了解决这个问题,MySQL采用了RR这种隔离级别,因为在RR中,会在更新数据的时候增加记录锁的同时增加间隙锁,可以避免事务乱序的情况发生。

为什么大厂要将隔离级别修改成RC?

RR与RC的区别

一致性读

一致性读,又称为快照读。快照即当前数据之前的历史版本。快照读就是使用快照信息显示基于某个时间点的查询结果,而不考虑与此同时运行的其它事务所执行的修改。

在MySQL中,只有RR和RC这两种隔离级别才会使用一致性读。

在RC中,每次读取都会重新生成一个快照,总是读取行的最新版本。也因此事务中每次select也可以看到其它已commit事务所做的修改。

在RR中,快照会在事务中第一次查询语句执行时生成,只有在本事务中对数据进行更改才会更新快照。也就是说,如果在本事务中已经执行了一次select,此时其它事务执行了更改数据的操作并已提交,那么你在本事务再次select时,你是看不到其它事务所做的更改。

在数据库的RC这种隔离级别中,还支持半一致读,一条update语句,如果where条件匹配到的记录已经加锁,那么InnoDB会返回记录最近提交的版本,由MySQL上层判断此是否真的需要加锁。

锁机制

数据库的锁,在不同的事务隔离级别下,是采用了不同的机制的。在MySQL中,有三种类型的锁,分别是Record Lock、Gap Lock和Next-Key Lock。

Record Lock表示记录锁,锁的是索引记录。

Gap Lock是间隙锁,锁的是索引记录之间的间隙。

Next-Key Lock是Record Lock和Gap Lock的组合,同时锁住索引记录和间隙。范围是左开右闭。

在RC中,只会对索引增加Record Lock,不会添加另外两种锁。

在RR中,为了解决幻读问题,三种锁都支持。

主从同步

在数据主从同步时,不同格式的binlog也对事务隔离级别有要求。

MySQL的binlog主要支持三种格式,分别是statement、row和mixed。

在RC中,只支持row格式的binlog。如果指定了mixed作为binlog格式,那么如果使用RC,服务器会自动使用基于row格式的日志记录。

在RR中,可以同时支持三种格式的binlog。

为什么选择RC?

大厂之所以使用RC,主要原因有二,其一是提升并发,其二是减少死锁。

为什么RC要比RR并发度好?

因为RC在加锁过程中,是不需要添加Gap Lock和Next-Key Lock的,只需要对要修改的记录添加行级锁就行了。另外,RC还支持半一致读,可以大大的减少了更新语句时行锁的冲突。对于不满足更新条件的记录,可以提前释放锁,提升并发度。

为什么RC可以减少死锁发生?

因为RR会增加Gap Lock和Next-Key Lock,这就使得锁的粒度变大了,那么就容易导致死锁的概率增大(占地太宽了,别人占不到地方了)。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197596.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • opengrok使用教程之单工程(上)

    opengrok使用教程之单工程(上)OpenGrok简介有些情况下,我们需要在GB级别甚至几十GB级别且随时不断更新的大型代码(比如Android源码)里面搜索阅读源码,那么我们自然而然会有以下一些基本的需求:能够快速搜索代码代码可存放于本地/服务器代码之间可以跳转跨平台易于维护…显然SourceInsight、ctags、grep等工具在这些场景下就不太适合,于是有了OpenGrok这类代码搜索引擎。先看看维…

    2022年5月29日
  • mac mysql管理工具_hadoop平台管理工具

    mac mysql管理工具_hadoop平台管理工具Mac平台的MySQL管理工具

    2022年8月22日
  • Django(9)url指定默认参数「建议收藏」

    Django(9)url指定默认参数「建议收藏」前言当我们访问网页的时候,后台返回列表中有n条数据,此时我们会使用分页,比如一页只展示10条,但是我们访问第一页的时候大多数情况下,都会给url一个默认值,访问的时候直接展示第一页数据案例我们的

    2022年8月7日
  • 构造有参数的线程ParameterizedThreadStart

    构造有参数的线程ParameterizedThreadStart构造有参数的线程就得需要用到ParameterizedThreadStart,查看从元数据可以看出ParameterizedThreadStart是一个委托,参数类型必须是Object类型。我们通过线程对象的Start方法可以将参数传入,如thread.Start(“20191230”),此时参数“20191230”就会传递给子线程要执行的方法。代码:classProgram…

    2022年7月15日
  • 很黄很暴力「建议收藏」

    很黄很暴力「建议收藏」 http://hen.huang.hen.bao.li/这网站有点意思,某种程度上起点舆论监督的作用吧既然你诚心诚意地问了,我们就大慈大悲地告诉你,为了防止世界被破坏,为了维护世界的和平,贯彻爱与真实的罪恶,可爱而又迷人的反派网站,很黄!很暴力!我们是穿梭在墙外的敢死队,互联网的明天等着我们,就是这样,喵!

    2022年10月14日
  • 单片机结构_单片机原理读书笔记

    单片机结构_单片机原理读书笔记文章目录Chapter1:51单片机结构1.1MCS-51单片机内部结构1.1.151单片机内部结构1.1.2核心部件CPU1.2存储器1.2.1ROM和RAM1.2.2普林斯顿结构、哈佛结构1.2.3片内存储器、片外存储器1.2.4程序存储器、外部数据、内部数据存储器1.3特殊功能寄存器1.4时钟电路和复位电路1.4.1时钟电路1.4.2基本时序单位1.4.3复位…

    2022年10月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号