会话级隔离级别必须在事务开始前设置,执行start transaction或dml后调用set session会报错;需连接后立即设置,且参数必须用连字符(如read-committed),大小写不敏感。

会话级隔离级别必须在事务开始前设置
一旦执行了 START TRANSACTION 或任何数据操作语句(如 SELECT、UPDATE),再调用 SET SESSION TRANSACTION ISOLATION LEVEL 就会报错:Can’t change transaction isolation level when a transaction is active。这不是警告,是硬性限制。
实操建议:
- 连接 MySQL 后,**立刻**执行隔离级别设置,再开启事务或执行业务 SQL
- 如果已处于事务中,必须先
COMMIT或ROLLBACK,才能重新设置 - 使用
SELECT @@transaction_isolation确认当前值,避免误判
支持的语法形式与参数写法
MySQL 接受两种等效写法,但参数格式有明确要求:必须用连字符分隔,且大小写不敏感;不能写成空格或下划线。
正确示例:
SET SESSION TRANSACTION ISOLATION LEVEL READ-COMMITTED; SET TRANSACTION ISOLATION LEVEL REPEATABLE-READ;
错误写法(会报错):
-
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED(缺连字符) -
SET SESSION TRANSACTION ISOLATION LEVEL read_committed(下划线非法) -
SET SESSION transaction_isolation = 'READ COMMITTED'(引号内格式仍需连字符)
设置后立即生效,但不改变全局默认值
会话级设置只影响当前连接,断开重连即恢复为全局默认值(通常是 REPEATABLE-READ)。它不会触发配置文件重载,也不需要重启服务。
常见误解场景:
- 你在终端 A 执行了
SET SESSION TRANSACTION ISOLATION LEVEL READ-COMMITTED - 终端 B 同时连接,
SELECT @@transaction_isolation仍返回REPEATABLE-READ - 你改了
my.cnf里的transaction_isolation,但没重启 MySQL —— 新连接仍可能沿用旧默认值
验证是否生效的最简方式
不要依赖记忆或文档,直接查变量值最可靠:
SELECT @@transaction_isolation;
返回结果应为字符串,如 'READ-COMMITTED'。注意它和 @@global.transaction_isolation 是两个独立变量,别混淆。
容易忽略的一点:某些客户端(如 DBeaver、Navicat)可能在连接池复用时缓存会话状态,导致多次执行 SET 后 SELECT @@transaction_isolation 仍显示旧值 —— 此时应新建连接或显式关闭/重建会话。











