mysql隔离级别需分全局、会话、事务三层验证:@@global.transaction_isolation仅影响新连接;@@transaction_isolation反映当前会话实际值;spring等框架的@transactional会动态覆盖会话级设置。

查全局默认值:用 @@global.transaction_isolation
全局设置只影响新建立的连接,已存在的会话完全不受影响。最直接的验证方式是执行:
SELECT @@global.transaction_isolation;返回值如
REPEATABLE-READ,说明 MySQL 启动时加载的配置文件(如 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf)里写了 transaction_isolation = REPEATABLE-READ。注意:8.0+ 必须用短横线写法,transaction_isolation 不能写成 tx_isolation 或下划线形式;5.7 可兼容两者,但推荐统一用新参数名。
查当前会话实际生效值:必须用 @@transaction_isolation
应用层常通过连接池复用连接,哪怕全局设为 READ-COMMITTED,某个连接也可能被代码手动执行过 SET SESSION transaction_isolation = READ-COMMITTED,之后就一直沿用该值。所以不能只信配置文件或全局变量。正确做法是连上后立刻查:
SELECT @@transaction_isolation;或等价写法
SELECT @@session.transaction_isolation;。返回值大小写敏感,且不含引号——比如 READ-COMMITTED 是合法值,read committed 或 'READ-COMMITTED' 都不是。
SET GLOBAL 和 SET SESSION 的权限与生效时机差异
修改全局隔离级别需要 SUPER 权限(8.0.12+ 改为 SYSTEM_VARIABLES_ADMIN),普通用户执行会报错 Access denied;而 SET SESSION 任意用户都能用。关键区别在于:
-
SET GLOBAL transaction_isolation = 'READ-COMMITTED':仅对后续新建连接生效,当前所有活跃会话保持原值不变 -
SET SESSION transaction_isolation = 'READ-COMMITTED':立即改变当前连接行为,但不影响其他连接,断开重连即失效 - 两者都不影响正在执行中的事务——也就是说,事务开始后才改隔离级别,本次事务仍按旧规则运行
InnoDB 实际支持的隔离级别有“隐形降级”
即使你执行了 SET SESSION transaction_isolation = 'READ-UNCOMMITTED',InnoDB 也不会真正启用脏读。它内部会把 READ-UNCOMMITTED 自动降级为 READ-COMMITTED,因为 MVCC 架构无法维护未提交版本的快照。验证方法是执行完设置后再查 SELECT @@transaction_isolation,你会发现返回的仍是 READ-COMMITTED。生产环境应避免依赖 READ-UNCOMMITTED,它在 InnoDB 中没有实际意义。
@Transactional(isolation = ...) 控制事务行为,这类声明式事务会在开启事务前自动调用 SET TRANSACTION ISOLATION LEVEL ...,覆盖连接池中连接的默认隔离级别。所以光看数据库侧的 @@transaction_isolation 值,可能和应用真实行为不一致。











