拿捏!隔离级别、幻读、Gap Lock、Next-Key Lock
Python涨薪研究所
共 4116字,需浏览 9分钟
·
2021-08-30 22:00
源 /艾小仙 文/ 艾小仙
锁
隔离级别
幻读、Next-Key Lock、MVCC
The so-called phantom problem occurs within a transaction when the same query produces different sets of rows at different times. For example, if a SELECT
is executed twice, but returns a row the second time that was not returned the first time, the row is a “phantom” row.
select
执行了两次,但是第二次比第一次多出来行记录,这就是幻读。select * from user where age=10 for update
,得到的结果是id为[1,2,3]的记录,再次执行查询,得到了结果为[1,2,3,4]的记录,这是幻读。select
查询,查询的都是快照版本,这个场景下因为都是基于MVCC来查询快照的某个版本,所以不会存在幻读的问题,也可以认为是解决了幻读的方案之一,对于RC级别来说,因为每次查询都重新生成一个read view,也就是查询的都是最新的快照数据,所以会可能每次查询到不一样的数据,造成不可重复读,而对于RR级别来说只有第一次的时候生成read view,查询的是事务开始的时候的快照数据,所以就不存在不可重复读的问题,当然就更不可能有幻读的问题了。lock in share mode
、for update
、insert
、update
、delete
这些需要加锁的操作。对于MVCC来说就是解决的快照读的场景,而对于当前读那么就是Next-Key Lock要解决的事情。select * from user where age=10 for update
,将会锁住user
表所有age=10
的行记录,所有对age=10
的记录的操作都会被阻塞。select * from user where age>1 and age<10 for update
,将会锁住age
在(1,10)的范围区间,此时其他事务对该区间的操作都会被阻塞。事务隔离级别设置为读已提交RC ,这样肯定没有间隙锁了。 Innodb_locks_unsafe_for_binlog
设置为1另外一种情况适用于主键索引或者唯一索引的等值查询条件,比如 select * from user where id=1
,id
是主键索引,这样只使用Record Lock就可以了,因为能唯一锁定一条记录,所以没有必要再加间隙锁了,这是锁降级的过程。
解决幻读
首先第一步Server层会来查询数据 存储引擎根据查询条件查到数据之后对数据进行加锁,Record Lock或者间隙锁,然后返回数据 Server层拿到数据之后调用API去存储引擎更新数据 最后存储引擎返回结果,流程结束
user
表有4个字段,id
是主键索引,name
是唯一索引,age
是普通索引,city
没有索引,然后插入一些测试数据,下面区分一下几种情况来说明是怎么加Next-Key Lock的,然后就知道为啥会没有幻读的问题了。没有索引
update user set city='nanjing' where city='wuhan'
会发生什么?city
是没有索引的,所以存储引擎只能给所有的记录都加上锁,然后把数据都返回给Server层,然后Server层把city
改成nanjing
,再更新数据。普通索引
select * from user where age=20 for update
。age
是一个普通索引,存储引擎根据条件过滤查到所有匹配age=20
的记录,给他们加上写锁,间隙锁会加在(10,20),(20,30)的区间上,因此现在无论怎样都无法插入age=20
的记录了id=11,age=20
或者id=21,age=20
的记录,这样就存在幻读了。age
普通索引上,还会加在主键索引上,因为数据都是在主键索引下对吧,这个肯定也要加锁的,为了看起来简单点,就不画出来了)唯一&主键索引
select * from user where name='b' for update
。name=b
的的记录的,也不存在幻读问题。id>1 and id<11
呢,实际上也是一样的锁定方式,不再赘述。总结
好文推荐
某程序员吐槽:太尴尬!四年不见的前女友来公司面试,自己还是面试官!
“要源码上门自取”,结果人真上门了!国内企业再惹争议
有个程序员老公该多爽???
END
顶级程序员:topcoding
做最好的程序员社区:Java后端开发、Python、大数据、AI
一键三连「分享」、「点赞」和「在看」
评论