切换语言为:繁体
InnoDB 行锁分类解读

InnoDB 行锁分类解读

  • 爱糖宝
  • 2024-08-12
  • 2053
  • 0
  • 0

行级锁每次操作均会锁定对应的行数据,锁定粒度最小,致使锁冲突发生的可能性最低,因而并发度最高。它被应用于 InnoDB 存储引擎之中,要知道,InnoDB 的数据是依据索引来组织的,行锁通过对索引上的索引项加锁来实现,并非针对记录加锁。
同时,InnoDB 行锁包含共享锁(S)和排他锁(X) ,而行锁的共享锁和排他锁还能够继续细分成为三类:记录锁间隙锁临键锁

记录锁(Record Lock)

  • 作用:锁定表中的单行记录,防止其他事务对其进行update或delete。

  • 情况:当执行精确匹配查询(例如 WHERE id = 1 )并且查询的索引是唯一索引时,会对匹配的行加记录锁。

  • 示例:假设有表 students ,其中 id 是主键,事务 A 执行 SELECT * FROM students WHERE id = 15 FOR UPDATE; ,此时就会对 id = 15 的这行数据加记录锁。

  • 图示:

InnoDB 行锁分类解读

间隙锁(Gap Lock)

  • 作用:锁定一个范围,但不包含记录本身,防止其他事务在这个间隙上insert,主要用于防止幻读。

  • 情况:在可重复读隔离级别下,对于范围查询(如 WHERE id > 5 ),如果查询的索引不是唯一索引,会使用间隙锁。

  • 示例:事务 B 执行 SELECT * FROM students WHERE age > 20 FOR UPDATE; ,假设 age 列上没有唯一索引,此时会对 age 值大于 20 的间隙加间隙锁。

  • 图示:

InnoDB 行锁分类解读

临键锁(Next-Key Lock)

  • 作用:是记录锁和间隙锁的组合,既锁住记录,又锁住记录前面的间隙。

  • 情况:在可重复读隔离级别下,当使用范围查询且查询的索引是唯一索引时,会使用临键锁。

  • 示例:事务 C 执行 SELECT * FROM students WHERE id >= 20 FOR UPDATE; ,如果 id 是唯一索引,会对 id >= 20的范围加临键锁。

  • 图示:

InnoDB 行锁分类解读

行锁

InnoDB的行锁包含共享锁(S)和排他锁(X),在实现方式上表现为记录锁、间隙锁、临键锁。
共享锁(S 锁):允许其他事务同时读取被锁定的数据,但不允许修改。
排他锁(X 锁):则具有排他性,不允许其他事务获取共享锁或排他锁来访问被锁定的数据。

两种锁的兼容情况如下:

锁类型 共享锁(S 锁) 排他锁(X 锁)
共享锁(S 锁) 兼容(✔) 冲突(×)
排他锁(X 锁) 冲突(×) 冲突(×)

常见的SQL,加锁情况:

SQL 行锁类型 加锁情况
SELECT 无锁 没有任何加锁
SELECT ... LOCK IN SHARE MODE 共享锁(S 锁) 需要在SELECT 查询末尾加上‘LOCK IN SHARE MODE’
SELECT ... FOR UPDATE 排他锁(X 锁) 需要在SELECT 查询末尾加上‘FOR UPDATE’
INSERT 排他锁(X 锁) 自动会加上排他锁
UPDATE 排他锁(X 锁) 自动会加上排他锁
DELETE 排他锁(X 锁) 自动会加上排他锁

总结

总之,InnoDB 丰富多样的行锁机制,从共享锁与排他锁的大分类,到记录锁、间隙锁和临键锁的具体形式,为数据库的事务处理和并发操作提供了精细且可靠的控制手段。熟悉并驾驭这些行锁,是实现高性能、稳定可靠的数据库系统的重要基石。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.