为什么MySQL在降级事务隔离级别后并发吞吐量大幅提升

阿辰小哥_5677

阿辰小哥_5677

2026-09-29

956人浏览

原创

read committed 能绕开间隙锁,因其禁用间隙锁(唯一约束等例外),仅对命中行加记录锁,且采用语句级mvcc快照,降低锁粒度与版本留存压力。

为什么mysql在降级事务隔离级别后并发吞吐量大幅提升

READ COMMITTED 为什么能绕开间隙锁

MySQL 在 REPEATABLE READ 下默认启用间隙锁(Gap Lock)和临键锁(Next-Key Lock),哪怕你只查主键,只要 WHERE 条件涉及索引范围(比如 WHERE status = 'pending' 或 WHERE id > 100),InnoDB 就可能锁住整段索引间隙。而 READ COMMITTED 会禁用间隙锁(唯一约束和外键检查除外),只对实际命中的行加记录锁(Record Lock)。

这意味着:

  • INSERT 不再被无故阻塞:比如事务 A 执行 SELECT * FROM orders WHERE user_id = 123 FOR UPDATE,在 RR 下会锁住 user_id = 123 对应的间隙;在 RC 下,只要没命中行,就不锁间隙,事务 B 可立刻插入新订单
  • UPDATE/DELETE 锁粒度更小、持有时间更短:RC 下锁只持续到语句结束(非事务结束),RR 下要等到 COMMIT 才释放
  • 死锁概率显著下降:尤其在 INSERT ... SELECT 或批量状态更新场景中,锁冲突路径大幅收窄

MVCC 快照生命周期缩短直接减少资源争用

REPEATABLE READ 使用事务级 MVCC 快照:事务启动时生成一次,整个事务期间复用。这要求 InnoDB 持有所有旧版本直到该事务结束,容易拖慢 purge 线程、撑高 innodb_history_list_length,进而影响全局性能。

READ COMMITTED 改为语句级快照:每次 SELECT 都基于最新已提交版本重新生成快照。虽然多了点版本过滤开销,但换来的是:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 旧版本数据可被更快清理,减少 undo log 占用和 purge 压力
  • 长事务不再绑架整个实例的版本链管理
  • 高并发下内存与 CPU 开销更平稳,不会因个别慢事务导致雪崩式延迟

为什么不是所有场景都适用 READ COMMITTED

降级隔离级别不是“开箱即用”的性能开关,它改变的是读一致性语义本身。以下情况必须提前验证:

  • 应用是否隐式依赖“可重复读”:比如先 SELECT COUNT(*) 判断是否存在,再 INSERT,且未建唯一索引——RC 下可能插入重复数据
  • ORM 是否硬编码了隔离级别:Spring 的 @Transactional(isolation = Isolation.REPEATABLE_READ) 会覆盖数据库配置
  • 范围查询逻辑是否假设结果集稳定:如某段代码认为 “两次 SELECT * FROM t WHERE c > X 行数不变”,RC 下必然失效
  • Binlog 格式是否为 ROW:RC 是 ROW 格式的强前提,否则主从不一致风险上升

连接池初始化阶段必须显式设置才生效

很多人改完 my.cnf 中的 transaction-isolation = READ-COMMITTED 就以为万事大吉,但老连接仍维持原会话级别,ORM 也可能在获取连接后立即开启事务,导致 SET SESSION 失败。

真正落地必须双保险:

  • 在连接池配置里加 initSql = "SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED"
  • 避免在事务中动态修改:一旦执行过 START TRANSACTION,再执行 SET SESSION TRANSACTION ISOLATION LEVEL ... 会报错 Can’t change transaction isolation level when a transaction is active
  • 确认 SELECT @@session.transaction_isolation 返回值,别只看 @@global.transaction_isolation

最易被忽略的一点:间隙锁的关闭不是绝对的——唯一索引等值查询失败时(比如查不到记录),InnoDB 仍会加间隙锁以保证唯一性,这点在 RC 和 RR 下行为一致。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3843

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

831

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1009

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5661

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2623

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5640

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7441

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1010

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

892

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 176人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 279人学习