Mysql的隔离级别
在 MySQL 中,隔离级别是用于控制多个事务之间相互影响的机制。MySQL 提供了四种标准的隔离级别,每种级别解决不同程度的并发问题(如脏读、不可重复读、幻读)。理解这些隔离级别对于设计高并发、数据一致性的数据库应用至关重要。
四种隔离级别
1. READ UNCOMMITTED(读未提交)
● 允许的现象:脏读、不可重复读、幻读。
● 特点:
○ 事务可以读取其他事务未提交的数据(脏读)。
○ 性能最高,但数据一致性最差。
● 示例场景:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
● 风险:可能读取到其他事务回滚的数据,导致数据不一致。
2. READ COMMITTED(读已提交)
● 解决的问题:脏读。
● 允许的现象:不可重复读、幻读。
● 特点:
○ 事务只能读取其他事务已提交的数据。
○ 每次查询可能读到不同结果(不可重复读)。
● 示例场景:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
● MySQL 默认级别:在 InnoDB 存储引擎中,这是 Oracle 和 SQL Server 的默认隔离级别。
3. REPEATABLE READ(可重复读)
● 解决的问题:脏读、不可重复读。
● 允许的现象:幻读。
● 特点:
○ 同一事务中多次读取同一数据的结果一致。
○ 通过 MVCC(多版本并发控制) 实现,无需加锁即可保证可重复读。
○ 可能出现幻读(Phantom Read):当查询范围数据时,另一个事务插入了新数据,导致两次查询结果不一致。
● 示例场景:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
● MySQL 默认级别:InnoDB 的 默认隔离级别,通过 间隙锁(Gap Lock) 解决幻读。
4. SERIALIZABLE(串行化)
● 解决的问题:脏读、不可重复读、幻读。
● 特点:
○ 最高的隔离级别,强制事务串行执行。
○ 通过对读取的每行数据加锁,导致并发性能最低。
● 示例场景:
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
● 适用场景:对数据一致性要求极高且并发需求低的场景(如银行转账)。
隔离级别与并发问题对比
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 加锁情况 |
|---|---|---|---|---|
| READ UNCOMMITTED | ✅ | ✅ | ✅ | 不加锁 |
| READ COMMITTED | ❌ | ✅ | ✅ | 行级锁(读取后释放) |
| REPEATABLE READ | ❌ | ❌ | ✅ | 行级锁 + 间隙锁 |
| SERIALIZABLE | ❌ | ❌ | ❌ | 表级锁(全量阻塞) |
查看和设置隔离级别
查看当前会话隔离级别
SELECT @@tx_isolation; -- 旧版本
SELECT @@transaction_isolation; -- 5.7+ 版本
设置当前会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
设置全局隔离级别(需重启生效)
修改 my.cnf 配置文件:
[mysqld]
transaction-isolation = READ-COMMITTED
InnoDB 的特殊实现
InnoDB 在 REPEATABLE READ 级别下,通过 MVCC + 间隙锁 解决了幻读问题:
● MVCC:每个事务读取的是数据的历史版本,避免了不可重复读。
● 间隙锁:当查询索引范围时,锁定索引间隙,防止其他事务插入新数据,从而避免幻读。
如何选择隔离级别?
- 优先使用默认级别(REPEATABLE READ):在保证数据一致性的同时,提供较高的并发性能。
- 读多写少的场景:使用 READ COMMITTED 减少锁冲突。
- 对一致性要求极高的场景:使用 SERIALIZABLE,但需牺牲并发性能。
- 避免使用 READ UNCOMMITTED:除非对数据一致性要求极低。
本文来自博客园,作者:leepandar,转载请注明原文链接:https://www.cnblogs.com/leepandar/p/18868102

浙公网安备 33010602011771号