← 返回首页
mysql的默认隔离级别?会有脏读现象吗?
MySQL 的默认隔离级别
MySQL(InnoDB 存储引擎)的默认事务隔离级别是 可重复读(Repeatable Read)。
可以通过以下命令查看当前隔离级别:
SELECT @@transaction_isolation;
-- 输出:REPEATABLE-READ
会有脏读现象吗?
不会有脏读。 可重复读(Repeatable Read)级别下,脏读、不可重复读和幻读都能被有效避免。
具体原理如下:
-
避免脏读和不可重复读:InnoDB 通过 MVCC(多版本并发控制) 机制实现。事务在第一次执行快照读(普通 SELECT)时生成一个 ReadView,后续所有读操作都复用这个 ReadView,因此无论其他事务是否提交修改,当前事务看到的始终是同一个数据快照版本。
-
避免幻读:InnoDB 在 RR 级别下使用 Next-Key Lock(临键锁,即行锁 + 间隙锁的组合),不仅锁住索引记录本身,还锁住记录之间的间隙,防止其他事务在该范围内插入新数据。
四种隔离级别对比
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交(Read Uncommitted) | ✅ 可能 | ✅ 可能 | ✅ 可能 |
| 读已提交(Read Committed) | ❌ 避免 | ✅ 可能 | ✅ 可能 |
| 可重复读(Repeatable Read) | ❌ 避免 | ❌ 避免 | ❌ 避免(InnoDB) |
| 串行化(Serializable) | ❌ 避免 | ❌ 避免 | ❌ 避免 |
值得注意的是,SQL 标准中 RR 级别并不保证解决幻读,但 InnoDB 通过 Next-Key Lock 在 RR 级别下额外解决了幻读问题,这也是 MySQL 选择 RR 作为默认级别的重要原因——在性能和一致性之间取得了很好的平衡。
补充:如何修改隔离级别
-- 设置当前会话级别
SET SESSION transaction_isolation = 'READ-COMMITTED';
-- 设置全局级别(新连接生效)
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
近年来不少互联网高并发应用会选择将隔离级别降为 读已提交(RC),原因是 RC 下没有间隙锁,锁冲突和死锁概率更低,适合以高并发写入为主的场景。