InnoDB 的可重复读(Repeatable Read, 简称 RR)隔离级别,以及 Next-Key 锁相关机制的工作原理如下:
RR级别用的Next-Key Lock,RC级别用的record锁。快照读利用MVCC机制读取modelView,第一次查询时会创建一个modelview快照,读取小于当前活跃最小事务min_ids的已提交记录,也能读取当前事务creator_ids里修改的记录。当前读即加锁的select语句和insert,update,delete语句,对该记录和间隙前后加锁,是next-key lock。
https://juejin.cn/post/7056583607929798692
InnoDB 的 Repeatable Read 隔离级别
InnoDB 的 Repeatable Read 隔离级别是为了确保在事务中多次读取到的数据是一致的。即在一个事务中,如果在某一时刻读取了某条记录,那么在整个事务过程中,即使其他事务对这条记录进行了修改,该事务再次读取该记录时,读到的内容仍然是第一次读取时的内容。
Next-Key Lock 机制
Next-Key Lock 是 InnoDB 在可重复读隔离级别下使用的一种锁机制,它结合了行锁和间隙锁。具体表现为在锁住行的同时,也锁住了行前面的间隙。这种锁机制可以防止幻读现象的发生。
读操作加锁机制
在 InnoDB 的可重复读隔离级别下,具体的加锁行为如下:
-
普通 SELECT 语句:
- 对于普通的
SELECT
语句,InnoDB 默认是不会加锁的,只是进行一致性读(即读取快照数据)。 - 如果查询涉及到的行已经被其他事务加了排他锁(例如
UPDATE
或DELETE
),当前事务读取时会等待这些锁释放。
- 对于普通的
-
加锁的 SELECT 语句:
- 对于显式加锁的查询,例如
SELECT ... FOR UPDATE
或SELECT ... LOCK IN SHARE MODE
,InnoDB 会对读取到的行加锁。 SELECT ... FOR UPDATE
会加排他锁(X 锁),阻止其他事务对这些行进行任何修改。SELECT ... LOCK IN SHARE MODE
会加共享锁(S 锁),允许其他事务读取但不允许修改这些行。
- 对于显式加锁的查询,例如
未加索引和查询加锁情况
-
没有索引的情况下:
- 如果查询的条件没有使用到索引,InnoDB 会进行全表扫描。在全表扫描过程中,InnoDB 可能会对所有扫描到的行加锁(如果是显式加锁查询)。
-
查询语句没有加锁:
- 如果查询语句本身没有加锁(即没有使用
FOR UPDATE
或LOCK IN SHARE MODE
),那么 InnoDB 会进行一致性读,不会对读取的行加锁。 - 在这种情况下,即使查询条件没有加索引,InnoDB 也不会加锁,只是读取快照数据。
- 如果查询语句本身没有加锁(即没有使用
总结
- 在 RR 隔离级别下,普通的
SELECT
语句不会加锁,只是进行一致性读。 - 显式加锁的
SELECT
语句会对读取的行加锁,防止其他事务的并发修改。 - 没有索引的查询会进行全表扫描,在显式加锁情况下可能会对所有扫描到的行加锁。
- 一致性读是通过 MVCC(多版本并发控制)实现的,保证在事务内多次读取到的数据一致。
希望这些信息能帮助你更好地理解 InnoDB 的 RR 隔离级别和 Next-Key 锁机制。如果有更多具体问题,欢迎继续提问!