是,但只对新建立的连接生效;已存在的连接保持原隔离级别不变。mysql事务隔离级别切换后,全局设置仅影响后续新建连接,长连接仍沿用初始化时的级别,且事务中无法动态修改。

MySQL 事务隔离级别切换会立即生效吗?
会,但只对新建立的连接生效;已存在的连接保持原隔离级别不变。这是最常被误判的一点——改了全局变量,却以为所有事务立刻“同步更新”。
-
SET GLOBAL transaction_isolation = 'READ-COMMITTED'只影响后续新建连接,不触发现有连接的事务行为变化 - 应用层若复用长连接(如连接池中的连接),这些连接仍按启动时协商的隔离级别运行,哪怕你刚改完配置
- MySQL 8.0+ 默认用
transaction_isolation,5.7 及以前用tx_isolation,混用会导致Unknown system variable错误
Spring Boot 应用里改隔离级别,为什么@Transactional(isolation = ...) 没起作用?
因为 Spring 的 @Transactional 隔离级别声明,只有在传播行为为 REQUIRED 或 REQUIRES_NEW 且底层连接尚未开启事务时才真正生效;否则它会被忽略。
- 如果当前线程已有活跃事务(比如外层方法已开启),内层
@Transactional(isolation = READ_UNCOMMITTED)不会重新设置连接隔离级别 - MySQL 本身不支持在事务中动态修改隔离级别,执行
SET TRANSACTION ISOLATION LEVEL ...会报错ERROR 1568 (25001): Transaction is active - 验证是否生效:在事务内执行
SELECT @@transaction_isolation,结果反映的是连接初始化时的值,不是注解声明的值
从 REPEATABLE-READ 切到 READ-COMMITTED,哪些 SQL 行为会变?
核心差异在幻读处理和一致性读机制,直接影响分页、统计类查询逻辑是否稳定。
- RR 级别下,普通
SELECT是快照读,整个事务看到同一个 MVCC 快照;RC 级别下,每次SELECT都生成新快照,可能读到其他事务新提交的数据 -
UPDATE ... WHERE name = 'x'在 RC 下可能只锁住命中的行(record lock),而 RR 下还会加间隙锁(gap lock),导致并发插入阻塞表现不同 - 如果你依赖
SELECT COUNT(*)+ 后续INSERT做“存在性校验”,RC 下可能出现重复插入,RR 下靠间隙锁能防止
如何安全完成线上 MySQL 隔离级别切换?
不能只改配置,必须配合连接重建与业务验证。重点是让旧连接自然退出,新连接按新规则接入。
- 先在从库或影子库验证:修改
my.cnf中transaction_isolation,重启 mysqld 或用SET PERSIST(8.0+)持久化,再连上去查SELECT @@global.transaction_isolation - 应用侧滚动重启:逐台重启服务实例,确保连接池销毁老连接、新建连接读取到新全局配置;避免所有实例同时重启引发连接风暴
- 切完后盯 30 分钟:重点看慢查日志里是否有新增的锁等待,以及业务监控中“唯一键冲突”“乐观锁失败”类错误是否突增——这是 RC 下幻读暴露的典型信号
真正的难点不在命令怎么写,而在确认每一处连接到底用的是哪个隔离级别。MySQL 不提供“查某个连接当前事务隔离级别”的实时视图(SHOW VARIABLES 返回的是会话级变量,但事务中它可能已被隐式覆盖),所以得靠 SELECT @@transaction_isolation 在事务空闲期主动查,而且得查对时机。











