MySQL表级锁、行级锁与多粒度锁(意向锁)

InnoDB锁

与其它存储引擎只支持表级锁不同,InnoDB存储引擎既支持表级锁,又支持行级锁。

常见的锁为:S锁(共享锁Share)和X锁(排它锁Exclusive),可以理解为读锁和写锁。

  • 两个读线程可以同时获得S锁,即S锁是自兼容的;
  • 但是写线程想获得X锁必须等S锁全部释放,且X锁被获取后S锁与X锁都无法被获取,即X锁不是自兼容的,且与S锁互不兼容。

一、表级锁

表级锁的粒度粗,直接将整个表都锁住,虽然解决了并发问题但是读写性能很差。

二、行级锁

行级锁的粒度细,只是将表中的某一行记录锁住,能够实现更加精准的并发控制,但是锁的开销比较大,可能出现死锁的情况。

行锁有三种类型:

  1. Record Lock:给单一行记录上锁,分为S型与X型,控制的是某一条记录。
  2. Gap Lock:给单一行记录上锁,其他线程无法在该记录前插入数据,用于SERIALIZABLE隔离级别解决幻读问题。
  3. Next-Key Lock:即Record Lock和Gap Lock的合体版,给某一行记录加锁的同时不允许在其之前插入数据。

行级锁的基本原理

  • InnoDB行级锁是通过给索引上的索引项加锁来实现的。只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁
  • 当表中锁定了其中的某几行时,不同的事务可以使用不同的索引锁定不同的行
  • 不论使用主键索引、唯一索引还是普通索引,InnoDB都会使用行锁来对数据加锁

三、意向锁(多粒度锁)

意向锁,包括意向共享锁(IS锁)与意向排它锁(IX锁)。意向锁用于标记整个表中行级锁的使用情况,可以快速判断当前表中是否有行级S锁和行级X锁。

  • 当线程加行级S锁之前,必须先加IS锁。
  • 当线程加行级X锁之前,必须先加IX锁。

注:IS锁和IX锁是自兼容且互相兼容的,可以有多个线程给表加IS锁和IX锁。

意向锁的好处在于:

  • 当线程加表级S锁之前,先查看IX锁是否全部释放,如果没有,说明表中有线程在写数据,此时无法获取表级S锁。
  • 当线程加表级X锁之前,先查看IS与IX锁是否全部释放,如果没有,说明表中有线程在读写数据,此时无法获取表级X锁。

如果没有意向锁,则获取表级锁之前需要到表中遍历对应的行级锁是否存在,这样效率太低了。

四、死锁问题

死锁是指两个及以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。

若无外力作用,事务都将无法推进下去。

死锁的解决方案

  1. 被动解决:设置超时时间。当一个事务超出设定的时间阈值时,则让它进行回滚。
  2. 主动解决:利用锁的信息链表和事务的等待链表建图,判断其中是否存在回路
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白龙码~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值