Innodb的七种锁

1)共享锁(S锁)和排他锁(X锁)

S锁和X锁都是行级锁

共享锁:事务要读取某行记录时,需要获得该行的S锁
排他锁:事务要修改某行记录时,需要获得该行的X锁

当事务A获得某一行的S锁,事务B想要访问该行时:
    B请求S锁,二者都有S锁。
    B请求X锁,操作阻塞,被拒绝。

当事务A获得某一行的X锁,事务B想要访问该行时:
    B请求S锁,操作阻塞,被拒绝。
    B请求X锁,操作阻塞,被拒绝。
兼容性S锁X锁
S锁兼容不兼容
X锁不兼容不兼容

S锁和X锁也可以是表级别锁

此时,兼容性与行级别锁效果一样

2)意向锁

意向锁是表级锁,不与行级锁冲突

它是一个事务在未来某一时刻,可能要加S或X锁时声明的一个意向。

为什么需要意向锁?
答:S和X是相互排斥的。当事务A希望给某表加一个S锁,需要保证:
1)该表其他事务对该表没有排他锁
2)该表其他事务对该表的每一行都没有排他锁
为了不去遍历每一行,而产生了意向锁。

意向锁的原理:
答:当事务A持有该表某一行的排他锁,此时该表就有意向排他锁和某一行的排他锁。
事务B要访问该表内容时,就会发现该表的意向排他锁,从而推断出,某事务必定持有该表的某一行的排他锁。
这样事务B的访问必然产生阻塞,不必去检测每一行的加锁情况。

意向共享锁:IS锁 格式select ... lock in share mode;
意向排他锁:IX锁 格式select ... for update;

兼容性S锁X锁IS锁IX锁
S锁兼容不兼容兼容不兼容
X锁不兼容不兼容不兼容不兼容
IS锁兼容不兼容兼容兼容
IX锁不兼容不兼容兼容兼容

3)记录锁(record key)

记录锁是最简单的行锁,只锁住一行。
记录锁永远加在索引上,即使一个表没有索引,InnoDB也会隐式的创建一个索引,并使用这个索引实施记录锁。它会阻塞其他事务对这行记录的插入、更新、删除。
在索引上加记录锁:select k1 from test where k1=2 for update;

4)间隙锁(gap key)

间隙锁锁住的是一个区间,加在两个索引中间,或者第一个索引之前,或者最后一个索引之后。
间隙锁是为了解决幻读问题。

5)临键锁(next-key lock)

它是记录锁和间隙锁的组合。
next-ley lock锁住该索引本身以及索引之前的间隙。
锁区间是前开后闭。(x,y]

6)插入意向锁(insert intention)

在插入一行记录的操作之前的一种间隙锁,释放插入的信号。

多个事务,在同一个索引,同一个范围区间插入记录时,如果插入的位置不冲突,不会阻塞彼此。

兼容性间隙锁插入意向锁记录锁临键锁
间隙锁兼容兼容兼容兼容
插入意向锁不兼容兼容兼容不兼容
记录锁兼容兼容不兼容不兼容
临键锁兼容兼容不兼容不兼容

7)自增锁

特殊的表级锁,针对AUTO_INCREMENT类型的列
如果一个事务正在往表中插入记录,所有其他事务的插入必须等待,以便第一个事务插入的行,是连续的主键值。

补充说明:
死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

解决死锁:
1)如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会;
2)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
3)对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
4)如果业务处理不好可以用分布式事务锁或者使用乐观锁;
5)死锁与索引密不可分,解决索引问题,需要合理优化索引
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值