【MySQL进阶之路 | 高级篇】行锁之记录锁和间隙锁

1. InnoDB的行锁

行锁(row lock)也称为记录锁。顾名思义,就是锁住某一行(某个记录row)。需要注意的是,MySQL服务层并没有行锁机制,行级锁只在存储引擎层实现。

优点:锁定力度小,发生锁冲突概率低,可以实现的并发度高。

缺点:对于锁的开销比较大,加锁会比较慢,容易出现死锁的情况。

InnoDB与MyISAM的最大不同有两点:一是支持事务;二是采用了行级锁。

a. 记录锁(recode locks)

记录锁也就是仅仅把一条记录锁上,官方的类型名称为: LOCK_REC_NOT_GAP。比如我们把id值为8的那条记录加一个记录锁的示意图如图所示。仅仅是锁住了id值为s的记录,对周围的数据没有影响。

例子:行锁的S锁

select * from student where id = 1 lock in share mode;

b. 间隙锁(gap locks)

MySQL在REPEATABLE READ隔离级别下是可以解决幻读问题的,解决方案有两种,可以使用MVCC方案解决,也可以采用加锁方案解决。但是在使用加锁方案解决时有个大问题,就是事务在第一次执行读取操作时,那些幻影记录尚不存在,我们无法给这些幻影记录加上记录锁。InnoDB提出了一种称之为Gap Locks的锁,官方的类型名称为:LOCK_GAP,我们可以简称为gap锁。比如,把id值为8的那条记录加一个gap锁的示意图如下:

图中id值为8的记录加了gap锁,意味着不允许别的事务在id值为8的记录前边的间隙插入新记录,其实就是id列的值(3, 8)这个区间的新记录是不允许立即插入的。比如,有另外一个事务再想插入一条id值为4的新记录,它定位到该条新记录的下一条记录的id值为8,而这条记录上又有一个gap锁,所以就会阻塞插入操作,直到拥有这个gap锁的事务提交了之后,id列的值在区间(3,8)中的新记录才可以被插入。

gap锁的提出仅仅是为了防止插入幻影记录而提出的。虽然有共享gap锁和独占gap锁这样的说法,但是它们起到的作用是相同的。而且如果对一条记录加了gap锁(不论是共享gap锁还是独占gap锁),并不会限制其他事务这条记录加记录锁或者继续加gap锁。

例子:

这里session 2并不会被堵住。因为表里并没有id=5这个记录,因此session 1加的是间隙锁(3,8)。也是在这个间隙加的间隙锁。它们有共同的目标,即:保护这个间隙,不允许插入值。但,它们之间是不冲突的。

注意,给一条记录加了gap锁只是不允许其他事务往这条记录前边的间隙插入新记录,那对于最后的间隙,也就是student 表中id值为20的记录之后的间隙该咋办呢?也就是说给哪条记录加gap锁才能阻止其他事务插入id值在(20,+正无穷)这个区间的新记录呢?这时候我们在讲数据页时介绍的两条伪记录派上用场了。

  • Infimum记录,表示该页面中最小的记录。
  • Suprenum记录,表示改页面中最大的记录。

为了实现阻止其他事务插入id值在(20, +oo)这个区间的新记录,我们可以给索引中的最后一条记录,也就是id值为20的那条记录所在页面的Supremum记录加上一个gap锁。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值