mysql事务级别持有锁的区别

四种隔离级别

隔离级别 可能的问题 特点
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️⃣ 具体功能差异

  1. READ UNCOMMITTED

    • 几乎不用锁,能看到别的事务未提交数据(脏读)。

    • SELECT 基本都是直接去表里读,没有 MVCC 保护。

  2. READ COMMITTED

    • SELECT 每次都会生成新的快照(语句级一致性)。

    • 锁:UPDATE/DELETE/SELECT ... FOR UPDATE 只锁到命中的记录,不会锁间隙 → 可能出现幻读

  3. REPEATABLE READ(MySQL 默认)

    • 事务启动时生成一致性快照,整个事务内的普通 SELECT 读到的数据保持一致(事务级一致性)。

    • 锁:SELECT ... FOR UPDATEUPDATEDELETE 会使用 Next-Key Lock(记录锁 + 间隙锁) → 阻止幻读。

    • INSERT 会加"插入意向锁",避免并发插入冲突。

  4. SERIALIZABLE

    • 普通 SELECT 也会加共享锁,防止别的事务写。

    • 本质上强制串行执行,避免所有并发问题,但性能最差。


4️⃣ 总结

  • RC:快照级一致性,每条 SELECT 都是最新提交的,但没有间隙锁 → 会出现幻读。

  • RR(MySQL 默认):事务级一致性,锁机制更强大(Next-Key Lock、间隙锁) → 避免大多数幻读。

  • Serializable:所有读都锁住,直接串行化 → 最安全最慢。