大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
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,这就使得锁的粒度变大了,那么就容易导致死锁的概率增大(占地太宽了,别人占不到地方了)。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197596.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...