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:每个事务读取的是数据的历史版本,避免了不可重复读。
● 间隙锁:当查询索引范围时,锁定索引间隙,防止其他事务插入新数据,从而避免幻读。

如何选择隔离级别?

  1. 优先使用默认级别(REPEATABLE READ):在保证数据一致性的同时,提供较高的并发性能。
  2. 读多写少的场景:使用 READ COMMITTED 减少锁冲突。
  3. 对一致性要求极高的场景:使用 SERIALIZABLE,但需牺牲并发性能。
  4. 避免使用 READ UNCOMMITTED:除非对数据一致性要求极低。
posted @ 2025-05-09 14:12  leepandar  阅读(120)  评论(0)    收藏  举报