当前位置: 首页
数据库
mysql为什么RC级别在高并发下更受欢迎_分析其对死锁与并发的优化

mysql为什么RC级别在高并发下更受欢迎_分析其对死锁与并发的优化

热心网友 时间:2026-05-04
转载

RC降低死锁概率的根本原因是默认不使用间隙锁,仅对命中行加记录锁,锁范围更小、冲突更少;而RR对范围条件自动加Next-Key锁,易引发循环等待死锁。

mysql为什么RC级别在高并发下更受欢迎_分析其对死锁与并发的优化

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

RC 隔离级别为什么能降低死锁概率

说到底,RC级别降低死锁概率的核心秘诀,就在于它“不轻易动用”间隙锁(Gap Lock)——除了检查唯一键或外键冲突这类少数特定场景。对比之下,在RR级别里,一句 UPDATE WHERE age > 25 这样的范围更新,InnoDB会默认加上Next-Key Lock(记录锁+间隙锁),把整个区间都锁住。而在RC级别下,它只锁定实际被修改的那些行,锁的范围大大缩小,事务之间“撞车”的可能性自然就降低了。

一个典型的死锁链条是这样的:事务A锁住了(10, 20)这个间隙,事务B锁住了(20, 30)这个间隙,然后它们都试图往中间插入一条id=25的记录,结果就是互相等待,直接卡死。但在RC级别下,这些间隙本身不会被锁定,不同事务的插入意向锁(Insert Intention Lock)之间是兼容的,因此这类因争夺“空隙”而引发的循环等待,基本可以避免。

几个关键差异,可以这样理解:

  • 在RR级别下,执行SELECT ... FOR UPDATE或带范围条件的UPDATE时,InnoDB会自动升级为Next-Key Lock。
  • 而在RC级别下,执行同样的SQL,通常只加记录锁(Record Lock)。当然,如果涉及唯一索引冲突检查,它仍然会加S型的Next-Key Lock来做重复性校验。
  • RC级别还能减少MVCC版本链的维护开销,尤其是在写多读少的场景里,undo log的清理压力会更小一些。
  • 最后要提醒一点:间隙锁缺失不等于完全没有锁。遇到外键约束或者唯一键冲突检测时,Gap Lock依然会被触发,这个细节常常被忽略。

RC 下 INSERT 死锁的真实诱因

很多人可能以为,切换到RC级别就彻底告别INSERT死锁了,其实不然。真正的陷阱,往往藏在唯一键冲突和主键冲突的锁行为里——在这些场景下,RC和RR的加锁策略是一致的。

举个例子,两个事务并发执行这样一条语句:

INSERT INTO users (id, email) VALUES (100, 'a@b.com');

如果email字段是唯一索引,并且表中已经存在一条email='a@b.com'的记录,那么两个事务都会尝试对这条已存在的记录加上S型的Next-Key Lock(目的是做冲突检测)。紧接着,它们又都会试图插入自己的新行,这就形成了X锁与S锁的互斥,死锁一触即发。

这里有几个关键点需要把握:

  • 使用INSERT ... ON DUPLICATE KEY UPDATE时,如果发生唯一键冲突,它会加X型的Next-Key Lock,在RC级别下同样可能引发死锁。
  • REPLACE INTO的行为更激进:它会在冲突记录以及它的下一条记录上都加上Next-Key Lock。
  • 即使没有显式地开启事务,单条INSERT语句本身也会开启一个隐式事务,锁要等到语句结束时才释放。
  • 如果一个没有索引的列被用来做唯一性判断?那情况会更糟,查询会退化为全表扫描并加上大量的记录锁,死锁风险反而可能更高。

RC 配置后为什么业务还出问题

配置了RC但业务依然出问题,最常见的原因其实是连接池或者ORM框架没有让配置真正生效。要知道,MySQL的默认隔离级别是RR,很多Ja va应用使用HikariCP配合MyBatis,连接从连接池取出后,其隔离级别可能依然沿用服务端的默认值,那条关键的SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED语句并没有被执行。

如何验证配置是否真的生效了呢?可以试试这几个方法:

  • 在连接建立后,立刻执行SELECT @@transaction_isolation进行查看。注意,要看的是会话级变量,而不是全局变量@@global.transaction_isolation
  • 检查慢查询日志,看看里面是否还有SELECT ... LOCK IN SHARE MODE这类语句。这类语句在RC下虽然不加Gap Lock,但如果没有显式地以BEGIN开启事务,它可能会按照会话的默认隔离级别(可能还是RR)来执行。
  • binlog格式必须设置为ROW,否则在RC级别下可能导致主从数据不一致。如果使用STATEMENT格式,RC下那些非确定性的语句将无法在从库正确重放。
  • Spring框架的@Transactional(isolation = Isolation.READ_COMMITTED)注解通常是有效的,但需要确认数据源本身的配置没有覆盖这个设置。

RC 不是银弹:哪些场景它反而更危险

必须清醒地认识到,RC并非万能解药,在某些场景下它反而会带来更大的风险。最典型的就是“先查询,后修改”这类业务逻辑。

以库存扣减为例:先执行SELECT stock FROM goods WHERE id = 123得到库存10,再执行UPDATE goods SET stock = 9 WHERE id = 123 AND stock >= 10。在RC级别下,这两个操作之间的时间窗口,其他事务可能已经把库存改成了9,最终导致超卖。

这时,你不得不借助SELECT ... FOR UPDATE来加锁。但问题在于,RC下的SELECT ... FOR UPDATE只锁行,不锁间隙。如果业务逻辑本身允许“幻读”(即允许在事务期间插入新记录),那没问题;但如果需要防止新记录的插入干扰判断(例如,防止在事务期间新增一个同规格的商品),RC就无能为力了。

还有一些容易被忽略的细节:

  • RC下,SELECT ... FOR UPDATE不会阻塞其他事务在相邻间隙中插入数据,所以如果业务需要“防止插入”,必须依靠应用层逻辑或数据库的唯一约束来兜底。
  • 长事务在RC级别下依然危险:虽然MVCC快照的维护开销较轻,但未提交的事务仍然会阻止purge线程清理undo log,长时间积累可能导致ibdata1文件膨胀。
  • 某些ORM框架自动生成的批量更新语句,即使在RC下,也可能因为where条件的顺序不一致,导致加锁顺序不同,从而引发死锁。

说到底,决定是否采用RC级别的关键,并不在于抽象的并发数字高低,而在于业务本身能否容忍不可重复读和幻读现象,以及开发团队是否有能力将核心的校验逻辑,收敛到单条具备原子性的SQL语句中去完成。

来源:https://www.php.cn/faq/2419345.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
mysql8.0索引跳跃扫描如何使用_优化联合索引非首列查询

mysql8.0索引跳跃扫描如何使用_优化联合索引非首列查询

MySQL 8 0 索引跳跃扫描:一个被误解的“优化捷径” 提到MySQL 8 0的索引跳跃扫描(Index Skip Scan),很多人的第一反应是:“终于可以不用管联合索引最左前缀原则了!” 但事实果真如此吗?先泼一盆冷水:它并非一个可以随意开关的“万能钥匙”,而是优化器在特定场景下才会动用的“

时间:2026-05-04 20:08
怎样在SQL查询中同时展示明细与合计行_使用UNION ALL连接聚合结果

怎样在SQL查询中同时展示明细与合计行_使用UNION ALL连接聚合结果

怎样在SQL查询中同时展示明细与合计行?使用UNION ALL连接聚合结果 先说一个核心判断:直接用GROUP BY是无法同时显示明细和合计的,因为它会折叠原始行、丢失明细。必须用UNION ALL将明细查询与单行聚合查询拼接,并且要求字段数、类型、顺序严格一致,最后通过ORDER BY或辅助排序字

时间:2026-05-04 19:36
PHP 8环境下怎么处理SQL注入_使用原生预处理配合强类型声明

PHP 8环境下怎么处理SQL注入_使用原生预处理配合强类型声明

PHP 8 防 SQL 注入:strict_types=1 + 真实预处理 + 类型校验 在PHP 8环境下防范SQL注入,如果还停留在“用了PDO::prepare就万事大吉”的认知,那风险可就大了。真实情况是,必须将强类型声明、严格绑定逻辑与预处理语句三者结合,形成一个完整的防御链条。否则,数字

时间:2026-05-04 19:35
SQL中如何实现按比例抽样数据 ROW_NUMBER与百分比筛选

SQL中如何实现按比例抽样数据 ROW_NUMBER与百分比筛选

SQL中如何实现按比例抽样数据:ROW_NUMBER与百分比筛选 用 ROW_NUMBER() 做比例抽样为什么容易出错 很多朋友一上来就想用 ROW_NUMBER() OVER (ORDER BY NEWID()) 给全表编号,然后取前百分之几。这个思路听起来挺顺,但实际一跑就发现不对劲。问题出在

时间:2026-05-04 19:35
mysql为什么RC级别在高并发下更受欢迎_分析其对死锁与并发的优化

mysql为什么RC级别在高并发下更受欢迎_分析其对死锁与并发的优化

RC降低死锁概率的根本原因是默认不使用间隙锁,仅对命中行加记录锁,锁范围更小、冲突更少;而RR对范围条件自动加Next-Key锁,易引发循环等待死锁。 RC 隔离级别为什么能降低死锁概率 说到底,RC级别降低死锁概率的核心秘诀,就在于它“不轻易动用”间隙锁(Gap Lock)——除了检查唯一键或外键

时间:2026-05-04 19:35
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程