mysql默认事务隔离级别是什么_mysql配置与行为分析

1次阅读

mysql默认隔离级别是repeatable read,innodb在5.7+中默认使用该级别,仅对快照读防止幻读,当前读仍可能幻读,需结合索引与锁机制综合防控。

mysql默认事务隔离级别是什么_mysql配置与行为分析

MySQL默认隔离级别就是REPEATABLE-READ

InnoDB(MySQL 5.7+ 默认存储引擎)的默认事务隔离级别是 REPEATABLE READ,不是 READ COMMITTED,也不是 SERIALIZABLE。这点和 oraclepostgresql 等主流数据库不同,容易在迁移或调优时踩坑。

验证方式很简单,在任意 MySQL 客户端执行:

select @@GLOBAL.transaction_isolation, @@session.transaction_isolation;

输出结果通常是:

@@GLOBAL.transaction_isolation @@SESSION.transaction_isolation
REPEATABLE-READ REPEATABLE-READ

注意:MySQL 5.6 及更早版本用的是 tx_isolation 变量名,命令要换成 SELECT @@GLOBAL.tx_isolation

为什么默认选REPEATABLE-READ?它真能防幻读吗

官方文档和很多资料说 InnoDB 在 REPEATABLE READ 下“解决了幻读”,但这是有前提的——仅针对**快照读(普通 SELECT)**。而**当前读(如 SELECT … for UPDATE、UPDATE、delete)仍可能遇到幻读**,因为 InnoDB 会加间隙锁(gap lock)或 next-key lock 来阻塞插入,但这依赖索引结构和查询条件是否命中索引。

  • 没走索引的 WHERE 条件 → 可能退化为表锁,或间隙锁失效 → 幻读风险高
  • WHERE 条件是等值且命中唯一索引 → 间隙锁不生效 → 其他事务仍可 INSERT 相邻值,造成幻读
  • 显式使用 SELECT ... LOCK IN SHARE MODEFOR UPDATE → 触发当前读,InnoDB 才真正尝试用锁规避幻读

所以不能只靠隔离级别“躺平”,得结合 SQL 写法、索引设计、是否需要加锁来综合判断。

怎么安全地改隔离级别?别只改 session

临时改当前会话级别很常见,比如调试时执行:

SET SESSION transaction_isolation = 'READ-COMMITTED';

但上线前如果想全局生效,必须改配置文件(如 /etc/my.cnf),否则重启后就回去了:

[mysqld] transaction_isolation = READ-COMMITTED

注意三点:

  • 配置项值必须用短横线分隔(READ-COMMITTED),不能写成下划线或大驼峰
  • 改完要重启 MySQL 实例(systemctl restart mysqld),SET GLOBAL 不持久
  • 某些云数据库(如阿里云 RDS、腾讯云 CDB)不开放全局变量修改权限,只能通过控制台参数模板设置

READ-COMMITTED vs REPEATABLE-READ:性能与行为差异在哪

切换隔离级别不是“越高级越好”。实际影响集中在三方面:

  • MVCC 快照生成时机READ COMMITTED 每次 SELECT 都新建 ReadView;REPEATABLE READ 在事务第一次 SELECT 时建一次,后续复用 → 后者一致性更强,但长事务可能拖慢 purge 线程
  • 锁范围:RC 下只对命中记录加行锁,不加间隙锁(除非外键或唯一约束检查);RR 下默认加 next-key lock → RC 并发写入冲突更少,但幻读风险明确存在
  • 主从延迟敏感度:RC 下 binlog 是 statement 格式时,某些函数(如 NOW()UUID())可能导致主从不一致;RR + ROW 格式更稳妥

真实项目中,若业务能接受“同一事务内两次 SELECT 结果可能不同”,且写多读少(如订单状态流),READ COMMITTED 往往更轻量;若强依赖事务内读一致性(如财务对账),就别动默认值。

最常被忽略的一点:应用层 ORM(如 mybatishibernate)可能隐式开启事务并指定隔离级别,此时数据库配置只是兜底,优先级低于代码传参。查问题前,先确认是不是框架自己设了 ISOLATION_REPEATABLE_READ 或类似值。

text=ZqhQzanResources