抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

一、什么是事务隔离?

事务隔离是指在并发环境下,多个事务之间的操作互不干扰,每个事务都能看到一致的数据状态。

二、四种标准隔离级别(由低到高)

隔离级别 脏读 不可重复读 幻读 说明
READ UNCOMMITTED ✅ 允许 ✅ 允许 ✅ 允许 最低隔离,性能最好,但问题最多
READ COMMITTED ❌ 禁止 ✅ 允许 ✅ 允许 每次读取都获取最新已提交的数据
REPEATABLE READ ❌ 禁止 ❌ 禁止 ⚠️ MySQL 特殊处理(通常禁止) 默认级别,保证同一事务内多次读一致
SERIALIZABLE ❌ 禁止 ❌ 禁止 ❌ 禁止 最高隔离,完全串行化执行

1. RU:能读到别人未提交的事务

几乎没有隔离。

2. RC:只读别人已经提交的

解决了脏读问题。RC每次SELECT都会重新生成一个快照,所以两次查询能查询到不同的数据。

3. RR

RR每次SELECT,在整个事务期间共享同一个快照。因此整个事务期间看到的数据都是一样的。
解决了脏读、不可重复读,但幻读没有解决,MySQL有自己的解决方案。

RR不是整个事务期间共享一个快照吗?为什么会出现幻读?

RR 下普通 SELECT 使用同一快照,不会幻读;幻读发生在当前读(加锁读)中,因为它需要访问最新记录而不使用快照,于是可能看到其他事务新插入的行,所以 InnoDB 使用 Next-Key Lock 防止幻读。

4. 串行化

读写都加锁,所有事务都串行。效率最低

三、三种并发问题详解

1. 脏读(Dirty Read)

  • 事务 A 读取了事务 B 尚未提交的数据。
  • 如果 B 回滚,A 读到的就是“脏数据”。

2. 不可重复读(Non-repeatable Read)

  • 事务 A 在同一事务中两次读取同一行,但结果不同。
  • 原因:事务 B 在 A 两次读之间修改并提交了该行。

3. 幻读(Phantom Read)

  • 事务 A 在同一事务中两次执行相同查询(如 SELECT * FROM t WHERE id > 10),但第二次结果集多出/少了行。
  • 原因:事务 B 在 A 两次查询之间插入或删除了满足条件的行并提交。

评论