mysql事务隔离级别变更仅对后续新启动的事务生效,已开启事务不受影响;set session仅修改会话变量,不回滚当前事务;innodb在事务启动时即固化mvcc快照与锁策略,中途切换会导致机制冲突、解析错乱甚至报错error 1568。

对已开启的事务完全无影响,隔离级别变更只作用于后续新启动的事务。
SET SESSION TRANSACTION ISOLATION LEVEL 生效时机
执行该语句时,仅修改当前会话的tx_isolation变量值,但不会回滚或中断正在运行的事务。InnoDB 在事务开始(第一个 SELECT 或 DML)时就已根据当时的会话隔离级别确定了 MVCC 快照生成策略和锁行为,后续无法动态切换。
- 事务 A 已在
REPEATABLE READ下启动 → 即使你立刻执行SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED,事务 A 仍全程按 RR 行为执行 - 事务 B 在 SET 之后才启动 → 才会真正使用新的
READ COMMITTED级别 - 若用
SET GLOBAL,只影响新连接,不影响任何已有连接(包括空闲连接)
为什么不能中途切换隔离级别?
InnoDB 的事务快照不是“按需读取”,而是“按需构建”:RR 级别下事务启动即固定 read view,RC 级别下每次 SELECT 都新建 read view。两者底层机制不兼容,强行切换会导致 MVCC 版本链解析错乱、锁范围误判,甚至死锁或数据不可见。
- RR 事务中,
SELECT不加锁、依赖一致性视图 → 若中途切到 RC,同一查询可能突然触发行锁或间隙锁 - RC 事务中,
UPDATE只锁匹配行 → 若中途切到 RR,可能额外加间隙锁,扩大阻塞范围 - MySQL 明确禁止在活跃事务中执行该 SET 命令,会报错:
ERROR 1568 (25001): Transaction is running, cannot change isolation level
升级/降级前必须检查的连接状态
直接改全局或会话级隔离级别,容易误伤长事务或后台任务。务必先确认哪些连接正持有事务:
- 查活跃事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TRX_STATE = 'RUNNING' - 查空闲但未提交的连接:
SELECT ID, USER, HOST, COMMAND, TIME, STATE FROM information_schema.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 60 - 特别注意应用连接池中的“假空闲”连接:它们可能刚执行完 DML,尚未 COMMIT,但
COMMAND显示为Sleep
真正需要隔离级别变更的场景,几乎都发生在应用重启或连接池重建之后;在线动态调整只适用于全新发起的事务,这点很容易被忽略。











