mysql间隙锁

一、间隙锁的基本概念

1.什么叫间隙锁

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(NEXT-KEY)锁。

2.间隙锁的产生

上面的文字很抽象,现在举个栗子,介绍间隙锁是怎么产生的:

假设有以下表t_student:(其中id为PK,name为非唯一索引)

idnamesexaddress
1zhaoyi0beijin
3sunsan1shanghai
4lisi0guangzhou
5zhouwu0shenzhen
6wuliu1hangzhou

这个时候我们发出一条这样的加锁sql语句:

select id,name from t_student where id > 0 and id < 5 for update;

这时候,我们命中的数据为以下着色部分:

idnamesexaddress
1zhaoyi0beijin
3sunsan1shanghai
4lisi0guangzhou
5zhouwu0shenzhen
6wuliu1hangzhou

细心的朋友可能就会发现,这里缺少了条id为2的记录,我们的重点就在这里。

select ... for update这条语句,是会对数据记录加锁的,这里因为命中了索引,加的是行锁。从数据记录来看,这里排它锁锁住数据是id为1、3和4的这3条数据。

但是,看看前面我们的介绍——对于键值在条件范围内但不存在的记录,叫做“间隙(GAP)”,InnoDB也会对这个“间隙”加锁。

好了,我们这里,键值在条件范围但是不存在的记录,就是id为2的记录,这里会对id为2数据加上间隙锁。假设这时候如果有id=2的记录insert进来了,是要等到这个事务结束以后才会执行的

二、间隙锁的作用

总的来说,有2个作用:防止幻读和防止数据误删/改

1.防止幻读

关于幻读的概念可以参考我这篇文章 https://blog.csdn.net/mweibiao/article/details/80805031 ,这里就不多做解释了

假设有下面场景

时间事务A事务B
T1select count(1) from t_student where id > 1; 
T2 insert into t_student values(2,'qianer',1,'nanjing');
T3 commit;
T4select count(1) from t_student where id > 1; 
T5commit; 

如果没有间隙锁,事务A在T1和T4读到的结果是不一样的,有了间隙锁,读的就是一样的了

2.防止数据误删/改

这个作用比较重要,假设以下场景:

时间事务A事务B
T1delete from t_student where id < 4; 
T2 insert into t_student values(2,'qianer',1,'nanjing');
T3 commit;
T4commit; 

这种情况下,如果没有间隙锁,会出现的问题是:id为2的记录,刚加进去,就被删除了,这种情况有时候对业务,是致命性的打击。加了间隙锁之后,由于insert语句要等待事务A执行完之后释放锁,避免了这种情况

三.使用间隙锁的隐患

最大的隐患就是性能问题

前面提到,假设这时候如果有id=2的记录insert进来了,是要等到这个事务结束以后才会执行的,假设是这种场景  

时间事务A事务B
T1select * from t_student where id>1 and id < 100 for update; 
T2 insert into t_student values(2,'qianer',1,'nanjing');
T3update t_student set xxxx where id=xxx; 
T4update t_student set xxxx where id=xxx; 
T5update t_student set xxxx where id=xxx; 
T6 
T7commit; 

这种情况,对插入的性能就有很大影响了,必须等到事务结束才能进行插入,性能大打折扣

更有甚者,如果间隙锁出现死锁的情况下,会更隐晦,更难定位

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值