[mysql] 读锁,写锁,行锁,间隙锁

本文详细解析InnoDB数据库中读写锁的工作原理,包括共享锁(读锁)和排他锁(写锁),以及它们如何影响并发操作。涵盖了表锁、行锁和间隙锁的区别,以及加锁规则实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 读写锁:

  1. select … lock in share mode:当前读,加读锁,又叫共享锁

  2. select … for update:当前读,加写锁,又叫排他锁

  3. innoDB里面,update,delete,insert都会自动给涉及的语句添加写锁

读锁(共享锁)

读取结果集的最新版本,同时防止其他事务产生更新的数据版本。

本读取模式在读取前后对资源处理如下:

  1. 读取行为发生之前,获取读锁。这意味着如果有其他尚未提交的事务已经修改了结果集,本读取模式会等待这些事务结束,以确保自己稍后可以读取到这些事务对结果集的修改。

  2. 读取行为发生之后,当前事务提交之前,本读取模式会阻塞其他事务对结果集的修改。

  3. 当前事务提交后,释放读锁。这意味着所有之前被阻塞的事务可恢复继续执行。

写锁(排他锁)

写锁拥有读锁的一切功能,同时它还额外具备阻止其他事务读取最新版本的能力。

本读取模式在读取前后对资源的处理如下:

  1. 读取行为发生之前,获取写锁。这意味着如果有其他尚未提交的事务已经修改了结果集,本读取模式会等待这些事务结束,以确保自己稍后可以读取到这些事务对结果集的修改。

  2. 读取行为发生之后,当前事务提交之前,本读取模式会阻塞其他事务对结果集的修改,也会阻塞其他事务对结果集最新版本的读取(注:其他事务仍可以读取快照版本)。

  3. 当前事务提交后,释放写锁。这意味着所有之前被阻塞的事务可恢复继续执行。

2 写锁的分类

数据库加写锁的时候可能会添加表锁,行锁和间隙锁

案例数据:表名 t

id(主键)c(普通索引)d(无索引)
555
101010
151515
202020
252525

表锁

表锁会锁定整张表,如果当前有用户正在执行写操作并且获取了写锁,这可能导致整张表被锁定,阻塞其他用户的读写操作。如果用户执行的是读操作,则会获取读锁,此时其他用户的并发读操作将被接受,写操作会被阻塞。

行锁

行锁的粒度是在每一条行数据,这意味行锁可以尽可能的支持并发处理,相应的行锁开销也会比较大。并且,在InnoDB中的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则行锁将会自动升级为表锁。

间隙锁

间隙锁(Gap Lock)是Innodb在提交下为了解决幻读问题时引入的锁机制。在可重复读隔离级别下,数据库锁是通过行锁和间隙锁(开区间)共同组成来实现的。(-∞,5)5(5,10)10(10,15)15(15,20)20(20,25)25(25,+supernum] (其中supernum是数据库维护的最大的值。)

临键锁(next-key lock)

间隙锁和行锁结合一起就是临键锁。左开右闭。(-∞,5](5,10](10,15](15,20](20,25](25,+supernum]

3 加锁规则

规则1:InnoDB的行锁是基于索引实现的,通过索引访问时使用行锁,如果不通过索引访问数据,InnoDB会使用表锁

  • update t set c=2 where c=5,c列有索引,加的是行锁
  • update t set d=2 where d=5,d列无索引,加的是表锁

规则2:走索引的时候

  1. 加锁的基本单位是(next-key lock),他是前开后闭原则
  2. 插叙过程中访问的对象会增加锁
  3. 索引上的等值查询–给唯一索引加锁的时候,next-key lock升级为行锁
  4. 索引上的等值查询–向右遍历时最后一个值不满足查询需求时,next-key lock 退化为间隙锁
  5. 唯一索引上的范围查询会访问到不满足条件的第一个值为止

案例:

  1. update t set d= d+ 1 where id = 10;,会添加id=10的行锁,因为是唯一索引,(5,10]的临键锁升级为行锁
  2. update t set d= d+ 1 where d = 10;,会添加(5,10]的临键锁和(10,15)的间隙锁,注意15右边是开的,因为是等值查询,id = 15 不满足id= 10的查询要求,临键锁退化为间隙锁
  3. select * form t where id >= 10 and id <11 for update;,会添加id=10的行锁(10,15]的临键锁
  4. select * form t where id >= 10 and id <11 for update;,会添加(5,10]和(10,15]的临键锁
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值