四种隔离级别
隔离级别 | 可能的问题 | 特点 |
---|---|---|
READ UNCOMMITTED(读未提交) | 脏读、不可重复读、幻读 | 几乎不加锁,事务能看到其他事务未提交的数据 |
READ COMMITTED(读已提交) | 不可重复读、幻读 | 读操作使用 快照读(语句级一致性),每次读到的都是最新提交数据;UPDATE/DELETE/SELECT ... FOR UPDATE 会加锁 |
REPEATABLE READ(可重复读,MySQL 默认) | 幻读(通过间隙锁解决,大部分场景已避免幻读) | 读操作使用 快照读 (事务级一致性);锁定读用到 记录锁 + 间隙锁 + Next-Key Lock |
SERIALIZABLE(串行化) | 无并发问题,但性能差 | 所有 SELECT 都会加共享锁(读阻塞写),强制事务串行执行 |
2️⃣ 锁行为对比
(只讨论 InnoDB,MyISAM 没事务)
操作 | READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE |
---|---|---|---|---|
普通 SELECT | 不加锁,看未提交数据 | 快照读(语句级一致性) | 快照读(事务级一致性) | 加共享锁,阻塞写 |
SELECT ... FOR UPDATE | 记录锁 | 记录锁(不加间隙锁) | 记录锁 + 间隙锁(Next-Key Lock) | 记录锁 + 间隙锁 + 阻塞读 |
SELECT ... LOCK IN SHARE MODE | 共享锁 | 共享锁(不加间隙锁) | 共享锁 + 间隙锁 | 共享锁,阻塞写 |
UPDATE / DELETE | 记录锁 | 记录锁(不加间隙锁) | 记录锁 + 间隙锁 | 记录锁 + 间隙锁 |
INSERT | 插入新行 | 插入新行 | 插入新行,可能触发"插入意向锁" | 插入新行,可能被阻塞 |
3️⃣ 具体功能差异
-
READ UNCOMMITTED
-
几乎不用锁,能看到别的事务未提交数据(脏读)。
-
SELECT 基本都是直接去表里读,没有 MVCC 保护。
-
-
READ COMMITTED
-
SELECT 每次都会生成新的快照(语句级一致性)。
-
锁:
UPDATE/DELETE/SELECT ... FOR UPDATE
只锁到命中的记录,不会锁间隙 → 可能出现幻读。
-
-
REPEATABLE READ(MySQL 默认)
-
事务启动时生成一致性快照,整个事务内的普通 SELECT 读到的数据保持一致(事务级一致性)。
-
锁:
SELECT ... FOR UPDATE
、UPDATE
、DELETE
会使用 Next-Key Lock(记录锁 + 间隙锁) → 阻止幻读。 -
INSERT 会加"插入意向锁",避免并发插入冲突。
-
-
SERIALIZABLE
-
普通 SELECT 也会加共享锁,防止别的事务写。
-
本质上强制串行执行,避免所有并发问题,但性能最差。
-
4️⃣ 总结
-
RC:快照级一致性,每条 SELECT 都是最新提交的,但没有间隙锁 → 会出现幻读。
-
RR(MySQL 默认):事务级一致性,锁机制更强大(Next-Key Lock、间隙锁) → 避免大多数幻读。
-
Serializable:所有读都锁住,直接串行化 → 最安全最慢。