Mysql 幻读&Next Key Lock详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 幻读&Next Key Lock详解相关的知识,希望对你有一定的参考价值。
参考技术A 幻读的定义是指,一个事务开启后,执行前后两次查询,两次查询中出现了新的数据,幻读仅针对数据的新增。比如: 表t中,id为主键,目前有数据1,5,10,20四条。
开始一个事务A,前后两次执行 select * from t where id < 10 for update;
开启一个事务B,在事务A第二次执行查询前,执行insert into t values( 2,...); 并提交事务(请暂时忽略这里能否成功执行!)。
此时在RC、RR隔离级别下都会导致事务A第二次查询能够查询到 事务B新增的数据 id = 2。
RC级别下能够看到不同结果就不做解释了。
对于RR隔离级别下,有了MVCC版本控制为什么还能读取到不同的结果呢?
这里要归功于 "for update"。
"for update" 会将快照读变为当前读,在当前读场景中,会自动读取最新的数据,而非快照数据。
分析一下,锁与当前读关系。了解什么情况下会加锁。了解 意向锁、共享锁、排它锁区别及各自在什么情况下使用。
行锁的概念都清楚,这里就不做补充了。
间隙锁实际上是指一个区间。
我们都知道,InnoDB 在RR事务隔离级别下解决幻读问题就是通过Next Key Lock (间隙锁+行锁)来实现的。而且,很多地方也有提到,如果对于读一致性要求不高的场景可以考虑使用RC隔离级别,允许幻读的发生。
还是上边说的那个实例,略微改动:
比如: 表t中,id为主键,目前有数据1,5,10,20四条。
开始一个事务A,前后三次分别执行
开启一个事务B,在事务A执行update前,执行insert into t values( 2,...); 并提交事务。
此时我们知道,事务A中第二次查询能够查到 事务B新增的数据,也就是产生了幻读。那么,按照SQL执行的顺序来说,事务B
mysql行锁/间隙锁/区间锁
锁
- 行锁 record lock
- 间隙锁 gap lock
- 区间锁 next-key lock
作用
防止幻读
什么时候会取得gap lock或者next-key lock
隔离级别有关,只在REPEATABLE READ或以上的隔离级别下的特定操作才会取得gap lock或nextkey lock。
UPDATE和DELETE时,除了对唯一索引的唯一搜索外都会获取gap锁或next-key锁。即锁住其扫描的范围。
简单来说,影响到的字段不是唯一的,会变为区间锁
如果是唯一的,会取得 行锁
select * from t where id = 1 for update;
只锁定一行记录
select * from t where id >5 for update;
锁定 (5,n] 的数据行
select * from t where field_a = 100 for update;
如果此字段没有索引,会变为表锁,因为需要一条一条遍历,否则只锁满足只字段的数据
- S 锁 共享锁,同一时刻都能读但只能一个人写
- X 锁 排他锁,同一时刻读写都只能一个资源操作
以上是关于Mysql 幻读&Next Key Lock详解的主要内容,如果未能解决你的问题,请参考以下文章
Mysql加锁过程详解-innodb下的记录锁,间隙锁,next-key锁