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会释放所有在此过程中获得所有锁
相关推荐
Liquad Li5 分钟前
AI 优化快消品生产调度:提升效率与响应速度的关键路径
服务器·数据库·人工智能
满分观察网友z32 分钟前
MySQL 分页的“灵异事件”:为什么我的排序总是不对劲?
数据库
时空无限1 小时前
ubuntu 22.04 pam 模块设置用户登录失败锁定
linux·数据库·ubuntu
言之。1 小时前
Django `transaction.atomic()` 完整使用指南
数据库·python·django
都叫我大帅哥1 小时前
MySQL并发事务:一场数据库的「修罗场」生存指南
mysql
是大强1 小时前
mongodb操作巨鹿
数据库·mongodb
运维全栈云原生工程师1 小时前
mongoDB集群
数据库·mongodb
收获不止数据库1 小时前
技术人生——第13集:回归本源,大道至“减”
数据库·人工智能·职场和发展·数据库开发·sql优化·数据库优化·数据库设计
Jie_171 小时前
【Linux】LVS(Linux virual server)
服务器·数据库·lvs
两圆相切1 小时前
Oracle数据泵详解——让数据迁移像“点外卖”一样简单
数据库·oracle