MySQL-锁机制2-间隙锁


一、事务的幻读问题

串行化隔离级别下如何解决事务并发存在的幻读问题?在MySQL事务章节中有提到幻读(虚读)。

虚读:一个事务的操作导致另一个事务前后两次查询的结果,数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)

在这里插入图片描述

这里的过滤条件包括等值查询、范围查询;间隙锁(gap lock)、 record lock(行锁)


二、主键索引(值不可以重复的)的间隙锁

在事务使用范围条件作为过滤,而不是相等条件检索数据,并请求共享或排他锁时,InnoDB存储引擎会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙(GAP)” ,间隙的范围和过滤条件一样的,InnoDB存储引擎也会对这个范围加锁,这种锁机制就是所谓的间隙锁。

举例来说, 假如 stu 表中只有 5 条记录, 其 uid 的值分别是 1,2,3,4,5,6, 下面的 SQL:

select * from stu where uid > 5 for update;

这个SQL是一个范围条件的检索,InnoDB存储引擎不仅会对符合条件的 uid 值为6的记录行加锁,也会对uid 大于 6(即使这些记录并不存在)的"间隙"加锁,防止其它事务在表的末尾增加数据

InnoDB存储引擎使用间隙锁的目的,为了防止幻读以满足串行化隔离级别的要求。对于上面的例子,在不使用间隙锁的情况下,如果其它事务插入了 uid 大于 5 的任何记录,那么本事务如果再次执行上述语句,查询结果的数据量发生变化,就说明发生幻读
串行化隔离级别下如何解决事务并发存在的幻读问题?通过间隙锁解决的。


三、二级索引(值可以重复的)的间隙锁

1、范围查询时

利用二级索引进行范围查询时,由于非主键索引的属性值可以重复,所以间隙锁的范围会变成大于等于这个值的左闭区间。通过例子来理解:age添加了辅助索引,查询年纪大于20的记录行

select *from stu where age > 20;

在这里插入图片描述

二级索引的值相等的话,主键按照升序排列,如上图中所示,该范围处在间隙锁的范围之中,所以会发生事务阻塞。


2、等值查询时

在串行化隔离级别下,对辅助索引做等值查询时,为了防止幻读,InnoDB存储引擎会对这个值所在的记录行添加行锁,并在记录行的两边添加间隙锁。例如下图:实际的索引树不会数据量不会这么小,这里只是为了方便画图

select *from stu where age > 19;

在这里插入图片描述

在这个例子中,间隙的范围在age为[15,19]和[19,23)的这么一个范围。


总结

串行化隔离级别下InnoDB存储引擎通过间隙锁来解决事务并发产生的幻读问题;在主键索引、唯一键索引,值不允许被重复的情况下与值可以重复的二级索引,它们的间隙范围是有所不同的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值