MySQL 默认事务隔离级别:从原理到实践全解析
你想知道 MySQL 的默认事务隔离级别,这是理解 MySQL 并发控制、解决脏读 / 幻读 / 不可重复读等问题的核心知识点。我会从「默认值」「隔离级别分类」「原理验证」「修改方法」四个维度详细讲解,让你不仅知其然,更知其所以然。
一、MySQL 默认事务隔离级别
1. 核心结论
- InnoDB 引擎 (MySQL 默认存储引擎)的默认事务隔离级别是:
REPEATABLE READ(可重复读); - MySQL 5.1 及以上版本均遵循此规则,这也是 MySQL 与其他数据库(如 Oracle 默认
READ COMMITTED)的核心区别之一。
2. 快速验证(实操命令)
你可以直接在 MySQL 客户端执行以下命令,查看当前默认隔离级别:
sql
-- 查看全局/会话级别的默认隔离级别
SELECT @@GLOBAL.transaction_isolation, @@SESSION.transaction_isolation;
-- 旧版本(MySQL 5.6及之前)用这个命令
SELECT @@GLOBAL.tx_isolation, @@SESSION.tx_isolation;
输出示例:
| @@GLOBAL.transaction_isolation | @@SESSION.transaction_isolation |
|---|---|
| REPEATABLE-READ | REPEATABLE-READ |
二、事务隔离级别的完整分类(ACID 中的 I)
SQL 标准定义了 4 种事务隔离级别,MySQL InnoDB 全部支持,级别从低到高如下(隔离性越强,并发性能越差):
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 核心说明 |
|---|---|---|---|---|
| READ UNCOMMITTED(读未提交) | ✅ | ✅ | ✅ | 最低级别,能读取其他事务未提交的数据,会导致脏读 |
| READ COMMITTED(读已提交) | ❌ | ✅ | ✅ | 只能读取其他事务已提交的数据,解决脏读,但仍有不可重复读 / 幻读 |
| REPEATABLE READ(可重复读) | ❌ | ❌ | ❌ | MySQL 默认,同一事务内多次读取同一数据结果一致,InnoDB 额外解决了幻读 |
| SERIALIZABLE(串行化) | ❌ | ❌ | ❌ | 最高级别,事务串行执行,完全解决并发问题,但性能极差(几乎不用于生产) |
关键概念解释(新手必看)
- 脏读 :读取到其他事务未提交的修改(比如事务 A 改了数据但没提交,事务 B 读到了这个未提交的修改,之后 A 回滚,B 读到的就是 "脏数据");
- 不可重复读:同一事务内,多次读取同一数据,结果不一致(比如事务 A 读了数据,事务 B 修改并提交,A 再读就变了);
- 幻读 :同一事务内,多次执行同一查询,返回的行数不一致(比如事务 A 查
age=20的用户有 10 个,事务 B 插入 1 条age=20的记录并提交,A 再查就变成 11 个,像 "幻觉")。
三、MySQL 默认级别(REPEATABLE READ)的核心原理
InnoDB 的REPEATABLE READ之所以能同时解决不可重复读和幻读,核心依赖两个机制:
1. 多版本并发控制(MVCC)
- 每个事务启动时,会生成一个只读快照(Read View),事务内所有读取都基于这个快照,不受其他事务提交的修改影响,因此能保证 "可重复读";
- 快照只对读操作生效,写操作(增删改)仍会锁定数据,保证一致性。
2. 间隙锁(Gap Lock)
- InnoDB 在
REPEATABLE READ级别下,会对索引记录之间的 "间隙" 加锁,防止其他事务插入数据,从而额外解决了幻读(这是 MySQL 对 SQL 标准的增强); - 示例:执行
SELECT * FROM user WHERE age = 20 FOR UPDATE,InnoDB 会锁定age=20的记录,以及age在 19-21 之间的间隙,阻止插入新的age=20的记录。
四、如何修改事务隔离级别
1. 临时修改(当前会话生效,重启失效)
sql
-- 设置当前会话的隔离级别为读已提交
SET SESSION transaction_isolation = 'READ-COMMITTED';
-- 验证修改结果
SELECT @@SESSION.transaction_isolation;
2. 永久修改(全局生效,需修改配置文件)
-
编辑 MySQL 配置文件(my.cnf/my.ini):
[mysqld] # 设置全局默认隔离级别为读已提交 transaction-isolation = READ-COMMITTED -
重启 MySQL 服务:
bash# Linux systemctl restart mysqld # Windows net stop mysql && net start mysql -
验证全局配置:
sqlSELECT @@GLOBAL.transaction_isolation;
3. 按事务临时修改(仅当前事务生效)
sql
-- 开启事务前设置
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
-- 事务内的操作使用读已提交级别
SELECT * FROM user WHERE age = 20;
COMMIT;
五、不同隔离级别的适用场景
| 隔离级别 | 适用场景 | 优缺点 |
|---|---|---|
| REPEATABLE READ | 绝大多数业务场景(电商、后台管理系统等) | 平衡隔离性和并发性能 |
| READ COMMITTED | 高并发写场景(如金融交易)、兼容 Oracle 业务 | 并发性能更好,仅解决脏读 |
| SERIALIZABLE | 数据一致性要求极高的场景(如对账、审计) | 一致性最好,并发性能极差 |
总结
- 核心默认值 :MySQL InnoDB 引擎的默认事务隔离级别是
REPEATABLE READ(可重复读),这是平衡隔离性和并发性能的最优选择; - 核心能力:该级别基于 MVCC 解决了不可重复读,基于间隙锁额外解决了幻读,比 SQL 标准的可重复读更强;
- 修改方式 :可通过
SET SESSION/GLOBAL临时 / 全局修改,或修改配置文件永久生效,按需适配业务场景。