事务的隔离级别介绍
事务隔离级别
- 定义:
- 事务隔离级别是数据库管理系统(DBMS)定义的规则,用于控制并发事务之间的隔离程度,解决数据一致性与性能的平衡。
- 四种级别(SQL 标准):
- 读未提交(Read Uncommitted):最低隔离,可读未提交数据。
- 读已提交(Read Committed):只能读已提交数据。
- 可重复读(Repeatable Read):同一事务内读一致。
- 串行化(Serializable):最高隔离,完全串行执行。
- 核心点:
- 隔离级别越高,一致性越强,性能越低。
1. 隔离级别详解
(1) 读未提交(Read Uncommitted)
- 定义:
- 一个事务可以读取另一个未提交事务的数据(脏数据)。
- 问题:
- 脏读(Dirty Read):读到未提交的修改,若回滚则数据错误。
- 示例:
- T1 修改
balance = 50
,未提交。 - T2 读到
balance = 50
,T1 回滚,T2 数据无效。 - 性能:
- 高并发,锁少。
- 使用:
- 极少用,仅容忍不一致的场景。
(2) 读已提交(Read Committed)
- 定义:
- 一个事务只能读取已提交的数据。
- 解决:
- 脏读。
- 问题:
- 不可重复读(Non-Repeatable Read):
- 同一事务内,多次读取同一数据可能不同(因其他事务提交)。
- 示例:
- T1 读
balance = 100
。 - T2 修改并提交
balance = 200
。 - T1 再次读到
balance = 200
。 - 实现:
- 行级锁 + 读已提交版本。
- 使用:
- 默认(如 Oracle),适合读多写少。
(3) 可重复读(Repeatable Read)
- 定义:
- 事务内多次读取同一数据,结果一致。
- 解决:
- 脏读、不可重复读。
- 问题:
- 幻读(Phantom Read):
- 事务内查询范围数据时,其他事务插入新行,导致“幻影”。
- 示例:
- T1 查询
age > 20
,得到 2 行。 - T2 插入一行
age = 25
并提交。 - T1 再次查询得到 3 行。
- 实现:
- MVCC(多版本并发控制)+ 快照读。
- 使用:
- MySQL InnoDB 默认,平衡一致性和并发。
(4) 串行化(Serializable)
- 定义:
- 事务完全隔离,按顺序执行。
- 解决:
- 脏读、不可重复读、幻读。
- 问题:
- 无并发问题,但性能最低。
- 示例:
- T1 执行时,T2 必须等待。
- 实现:
- 表级锁或串行调度。
- 使用:
- 高一致性需求(如银行核心交易)。
2. 并发问题总结
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 是 | 是 | 是 |
读已提交 | 否 | 是 | 是 |
可重复读 | 否 | 否 | 是 |
串行化 | 否 | 否 | 否 |
3. MySQL InnoDB 实现
- MVCC:
- 每个事务有版本号,读时取快照(Read View)。
- 可重复读:事务开始时的快照。
- 读已提交:每次查询新快照。
- 锁机制:
- 读锁(S Lock):共享,允许多读。
- 写锁(X Lock):独占,阻止读写。
- 串行化用表锁。
- 间隙锁(Gap Lock):
- 可重复读下防止幻读,锁定范围。
示例
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM user WHERE id = 1; -- 读已提交
COMMIT;
4. 设置与查看
- MySQL 设置:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
- 查看:
SELECT @@transaction_isolation; -- MySQL 8.0+
SELECT @@tx_isolation; -- 老版本
5. 延伸与面试角度
- 与性能:
- 低隔离(如读未提交)并发高,一致性差。
- 高隔离(如串行化)一致性强,吞吐量低。
- Spring 集成:
@Transactional(isolation = Isolation.REPEATABLE_READ)
。- 实际应用:
- 订单:可重复读防重复扣款。
- 报表:读已提交容忍变化。
- 面试点:
- 问“级别”时,提四种及问题。
- 问“实现”时,提 MVCC 和锁。
总结
事务隔离级别从读未提交到串行化,逐步解决脏读、不可重复读、幻读,MySQL InnoDB 用 MVCC 和锁实现,默认可重复读。隔离与性能需权衡,面试时可提并发问题或画事务示例,展示理解深度。