MySQL的间隙锁问题

MySQL的间隙锁【Next-Key锁】

什么是间隙锁

间隙锁是一个在索引记录之间的间隙上的锁

其中间隙锁的使用就是为了保证某一个间隙内的数据在锁定情况下不发生任何的变化,例如MySQL的默认隔离级别为可重复读(RR),则其使用间隙锁的目的即是为了防止幻读

MySQL中的间隙锁场景

我们假设有下面的场景:id作为主键,number字段上有一个非唯一索引的二级索引,那么此时哪些场景不能再插入number = 5的记录??

在这里插入图片描述

答:只有我们保证number之前,number = 5现有记录之间,以及number之后不能插入新的记录,则新的number = 5的记录就不能插入进来!!

那么MySQL底层是怎么做到的,即使用到了我们的间隙锁!!!

在这里插入图片描述

此时我们锁住了(4,5),(5,5),(5,11)之间的间隙,则number = 5的记录就无法在插入进去了。。。

间隙锁锁定的区域

我们根据检索条件(number = 5)向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。
在上面的场景中,检索条件where number = 5的话,那么间隙锁的区间范围为(4,11),也就是我上面在右侧画出来的几部分之和。

间隙锁的目的是为了防止幻读,其主要通过两个方面实现这个目的:

  • (1)防止间隙内有新数据被插入
  • (2)防止已存在的数据,更新成间隙内的数据(例如防止numer=4的记录通过update变成number=5)

InnoDB使用间隙锁的条件

(1)必须在RR级别
(2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

场景判断

对于上面的案例,我们观察一下几个案例,来熟悉一下间隙锁的使用:

案例1:

session 1:
start  transaction ;
select  * from news where number = 4 for update ;

session 2:
start  transaction ;
insert into news value(2,4);#(阻塞)
insert into news value(2,2);#(阻塞)
insert into news value(4,4);#(阻塞)
insert into news value(4,5);#(阻塞)
insert into news value(7,5);#(执行成功)
insert into news value(9,5);#(执行成功)
insert into news value(11,5);#(执行成功)

在这里插入图片描述

此时我们查询的是number = 4的条件,此时它会锁定区域【2,4】以及【4,5】,所以此时前三条对于该间隙中的记录的插入操作均阻塞,必须等到select for update事务提交以后才会执行,而后面的几条不在该间隙锁的间隙范围内的操作均可以成功。

案例2:

session 1:
start  transaction;
select * from news where number>4 for update;

session 2:
start  transaction;
update news set id=2 where number=4 ;#(执行成功)
update news set id=4 where number=4 ;#(阻塞)
update news set id=5 where number=5 ;#(阻塞)
insert into news value(2,3);#(执行成功)
insert into news value(null,13);#(阻塞)

在这里插入图片描述

此时检索条件为范围查询:number > 4,故我们选择向左找到了最靠近4的值作为左区间,向右取无穷大作为右值,即我们的索引的范围【4,无穷大】

那么对于事务2来说:当我们的number在此间隙区间内的,就会阻塞住,防止插入新的记录导致幻读的发生。

总结

  • next-key(间隙锁)其实包含了记录锁和间隙锁,即锁定了一个范围,并且索引记录本身,InnoDB默认加锁方式为next-key锁
  • 对于主键索引或者是唯一索引,因为其都具有唯一性,故我们不可能重复插入相同的索引对应的记录,则我们对其只会索引当前行,即行锁,不会使用间隙锁。
  • MVCC(多版本并发控制)解决的是不可重复读的问题,间隙锁解决的是幻读问题。

故我们不可能重复插入相同的索引对应的记录,则我们对其只会索引当前行,即行锁,不会使用间隙锁。

  • MVCC(多版本并发控制)解决的是不可重复读的问题,间隙锁解决的是幻读问题。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值