首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么大多数公司使用MySql的事务隔离级别是RC?

本文所有的前提是MySQL的存储引擎是Innodb。

我们知道MySql的默认事务隔离级别是RR(可重复读),那么为什么大多数公司使用MySql时选择的事务隔离级别却是RC(读提交)呢?

一、事务隔离级别

数据库的事务隔离级别有读未提交、读提交、可重复读、串行化。其中在读未提交隔离级别下会存在脏读的问题,串行化执行效率低下,所以一般在读提交和可重复读两种隔离级别下选择。

读提交避免了脏读的现象,但没有解决幻读的问题;而可重复读解决了幻读的问题。

二、幻读

什么是幻读?

在一个事务中,前后两次查询同一范围(相同的查询SQL)的数据,返回的结果不一致,需要注意的是,不一致是指后一次查询的结果有前一次查询结果所没有的数据,也就是有新的数据被插入到这个范围中。而且幻读仅仅针对的是当前读,快照读是不会出现幻读。

看到上面对幻读的说明,一般都会有以下疑问:

两次查询的结果中的数据行是一样的,只是某些行的数据没修改了,比如某一行的字段被修改了,这种也算两次查询的结果不是完全一样,算不算幻读?

什么是当前读和快照读,两者有啥区别?

疑问1的情况不是幻读,是属于脏读,只有在读未提交隔离级别下才会发生。

当前读,指的是读取的是当前最新数据,并且会对读取的记录加锁,加什么样的锁跟事物隔离级别相关,主要包括如下情况:

快照读,指的是单纯的select语句。

怎么解决幻读?

MySql在可重复读的隔离级别下解决了幻读的问题。

首先,看下面这个例子:

1. 首先创建一个t_demo表,并插入几条数据。

2. RC下事务执行的情况

如果在RC隔离级别下,Session B在执行update时会被阻塞直到t4时刻Session A事务提交,而在t3时刻的Session C执行insert时不会被阻塞,导致Session A在t1和t4时刻两次相同的查询条件下查出来的结果是不一样的,这就是在RC隔离级别下出现幻读的情况。

这个例子可以看出RC是可以解决脏读的问题,无法避免幻读的现象,主要原因是在RC隔离级别下,对需要加锁的数据加的是行锁,只能对已经存在的记录行进行加锁,而插入的是一个没有存在的新的记录行。

3. RR下解决幻读

为了解决幻读的问题,引入了间隙锁(Gap Lock)和临键锁(Next-key Lock)。

间隙锁,锁定索引记录之间的间隙,用开区间来表示。比如上面插入的记录就有间隙,(- ∞,1),(1,5),(5,10),(10,15),(15, ∞)。

临键锁,间隙锁和行锁组成临键锁,前开后闭区间来表示。

一般而言,当前读能命中具体的记录则会加行锁,否则会根据间隙情况,加间隙锁,防止出现幻读。具体加锁情况要分为走索引的,不走索引的两大类,具体的加锁情况在这里不展开讨论,

三、为什么很多公司选择mysql的事务隔离级别是RC?

从以下两个方面来看,

1、使用RR事务隔离级别,能避免幻读,但是由于引入间隙锁导致加锁的范围可能扩大,从而会影响并发,还容易造成死锁,因为间隙锁和间隙锁是不冲突的;

2、在大多数业务场景下,事务隔离级别RC基本上能满足业务需求,幻读出现的机率较少;

从够用的角度来看,选择RC隔离级别是可以的。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20211123A01B5O00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券