MySQL行锁、记录锁、间隙锁、临建锁、意向锁、表锁

1、行锁

行锁实际上是加在索引上的,因此当执行的加锁的语句的条件列若是没有索引的的时候,此时加的就不是行锁,而是表锁

2、三种行锁

记录锁:MySQL会为该行的索引加上锁,避免其他的并发事务同事操作这一条数据。例如:select * from user where id = 1 for update,此时就会为id=1的这条记录加上记录锁。

间隙锁:它会锁定记录的间隙,间隙锁是不包含该索引记录本身的,是为了那些不存在的记录加锁。例如当前表中有id为1,5,9的三条记录,那么此时就存在(负无穷,1)、(1,5)、(5,9)、(9,正无穷)四个区间,间隙锁可以锁定上面的区间,避免其他并发事务往这些区间插入数据,利用这样的方式去解决RR隔离级别下部分幻读的问题。

临建锁(Next-Key Lock):可以理解为行锁+间隙锁的组合,间隙锁不锁定当前记录本身,而临建锁它实在锁住对应的区间的情况下,还会将当前记录也锁住,为当前记录加上记录锁,而在innodb存储引擎中,RR隔离级别的情况下,默认会采用临建锁去进行加行锁。但是针对不同的情况下,它可能会调整为记录锁、表锁以及间隙锁。

3、锁的调整情况

当对唯一索引去进行匹配时,对一个已经存在的数据去做等值判断,此时使用的是记录锁。

如果条件列没有索引,此时无法加行锁,此时用的就是表锁。

如果对唯一列做等值查询,且该加锁的记录不存在时,那么此时就使用间隙锁。例如表中有id=2,9这两条数据,此时当我们update ... id = 5的时候,那么就会对(2,9)这个区间加一个间隙锁

如果是对非唯一的普通索引做等值查询时,向右遍历的最后一个值不满足查询条件的时候,则会退化为一个间隙锁,这个原因是由于非唯一索引不能仅仅锁住当前记录本身,还要锁住下一个大于当前值的索引的间隙,避免由于插入重复的记录,导致出现幻读。例如有索引age=20,25这两条数据,当我们要对20去进行加锁的时候,由于是非唯一索引,因此还会继续向右遍历数据直到25,会锁住(20,25)之间的间隙,避免因为重复插入20导致出现幻读

如果是对唯一索引进行范围查询时,会一直向范围方向遍历到第一个不满足查询条件的值为止,知道正负无穷大,例如有id=80,88这条件记录,加锁的条件为id>=80,那么此时则会为80加上记录锁,(80,88)以及(88,正无穷)会加上对应的间隙锁,那这也就是组合起来变成临建锁

4、总结

MySQL锁是加在索引记录上面的。

如果是非唯一性索引,不论表中是否存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。

如果是唯一索引,如果表中存在该记录,只对该行记录加锁。如果表中不存在该记录,除了会对该记录所在范围加锁,还会向右遍历到不满足条件的范围进行加锁。

5、意向锁

一个表中有许多记录,一个事务为表中的某一行数据添加了行锁,另一个事务需要为该表添加表锁的时候,如何知道这个表中还有没有其他的行锁呢?

当需要加行锁的时候,MySQL会先为当前表加上意向锁,若此时有其他事务需要申请表锁的时候,则只需要判断该表是否存在兼容的意向锁即可。不需要遍历所有的行来判断是否存在行锁。

有了意向锁,不能再申请表锁,但是如果锁的不是同一行,其他事务是可以申请行锁的。

6、二级索引的更新加锁过程

  1. MySQL首先会在二级索引上找到对应的索引记录 并对其加锁
  2. 然后,因为二级索引中包含了对应行的主键值, MySQL会使用这个主键值来定位主键索引中的记录
  3. 一旦找到了主键索引中的记录,MySQL会对这 个记录加锁
  4. 在锁定了必要的索引记录之后,MySQL会执行 实际的数据更新
  5. 如果更新的列是二级索引的一部分,那么 MySQL还需要更新二级索引中的记录
  6. 更新完成后,MySQL会释放所有在此过程中获得所有锁
相关推荐
Polar__Star3 分钟前
Golang bcrypt如何加密密码_Golang密码加密教程【收藏】
jvm·数据库·python
澄澈青空~23 分钟前
有一个叫R2C,也有一个叫G2C
java·数据库·人工智能·c#
weixin_5860614625 分钟前
如何用 event.composedPath 获取事件触发经过的所有节点
jvm·数据库·python
weixin_4087177736 分钟前
如何用 Iterator.from 将类数组转化为具备现代方法的迭代器
jvm·数据库·python
努力努力再努力wz37 分钟前
【MySQL入门系列】掌握表数据的 CRUD:DML 核心语法与执行逻辑解析
android·开发语言·数据结构·数据库·c++·b树·mysql
深念Y42 分钟前
图数据库 vs 向量数据库:AI时代的两个“最强大脑”
数据库·人工智能·neo4j·图论··向量·rag
2301_7826591844 分钟前
SQL视图能否用于数据仓库模型_雪花模型与视图构建
jvm·数据库·python
m0_377618231 小时前
CSS如何让文字超出两行显示省略号_使用line-clamp属性限制
jvm·数据库·python
m0_743623921 小时前
HTML5中LocalStorage存储用户自定义快捷键配置
jvm·数据库·python
2301_773553621 小时前
HTML5中SharedWorker生命周期与浏览器进程关闭的关系
jvm·数据库·python