《MySQL——幻读与next-key lock与间隙锁带来的死锁》

create table 't' ('id' int(11) not null,'c' int(11) default null,'d' int(11) default null,primary key ('id'),key 'c' ('c')
) engine = InnoDB;insert into t values(0,0,0),(5,5,5),(10,10,10),(15,15,15),(20,20,20),(25,25,25);

该表除了主键id,还有索引c。

问下面的语句序列,是怎么加锁的,加的锁又是什么时候释放的呢?

begin;
select * from t where d = 5 for update;
commit;

这条语句会命中d=5这一行,对应主键id=5,因此在select语句执行完成后,id=5这一行会加一个写锁,并且由于两阶段锁协议,这个写锁会在执行commit语句的时候释放。

由于字段d上没有索引,因此这条查询语句会做全表扫描,那么,其他被扫描的不满足的行记录会不会被加锁?

幻读现象

如果旨在id=5这一行加锁,而其他行不加锁,在下面这个情况下:
在这里插入图片描述
session A执行了三次当前读,并且加上了写锁。

幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。

幻读与不可重复读的区别

在同一个事务中,两次读取到的数据不一致的情况称为幻读和不可重复读。幻读是针对insert导致的数据不一致,不可重复读是针对 delete、update导致的数据不一致。

1、在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。

2、session B的修改结果被session A之后的select语句用当前读看到,不能称为幻读。幻读仅仅指"新插入的行"

幻读带来的问题

1、破坏语义。

session A在T1就说了,把d=5的行锁住,不准别的事务进行读写,此时被破坏。

因为如果我们这时插入d=5的数据,这条新的数据不在锁的保护范围之内。

2、数据一致性问题

锁的设计是为了保证数据的一致性,不止是数据库内部数据状态在此刻的一致性,还包含了数据和日志在逻辑上的一致性。

即使给所有行加上了锁,也避免不了幻读,这是因为给行加锁的时候,这条记录还不存在,没法加锁 。

也就是说即使把所有的记录都上锁了,还是阻止不了新插入的记录

如何解决幻读

产生的幻读的原因是:行锁只能锁住行

为了解决幻读问题,InnoDB引入新的锁:间隙锁(Gap Lock)

间隙锁,锁的就是两个值之间的空隙,比如在表t,初始化插入了6个记录,就产生了7个间隙:
在这里插入图片描述

执行:

select * from t where d = 5 for update

6个记录加上了行锁,同时加上了7个间隙锁。

间隙锁与行锁有点不一样

行锁可以分为读锁与写锁
在这里插入图片描述

与行锁有冲突关系的是另外一个行锁。

间隙锁不一样,间隙锁之间不存在冲突关系。

与间隙锁存在冲突关系的,是"向间隙中插入一个记录"这个操作。

举例:
在这里插入图片描述
由于表t中并没有c=7这个记录,所以session A加的是间隙锁(5,10)。而session B也是在这个间隙加的间隙锁,它们的目标都是保护这个间隙,不允许插入值,所以两者不冲突。

next-key lock

间隙锁与行锁合称next-key lock,每个lock都是前开后闭区间。间隙锁是开区间。

如上面我们插入数据,使用:

select * from t for update

形成了7个next-key lock,分别是:

(-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]

supremum是一个不存在的最大值。

next-key lock 的引入解决了幻读问题,但是也带来了新的问题。

如,现在有这样一个业务逻辑:

任意锁住一行,如果这一行不存在的话就插入,如果存在这一行就更新它的数据。

begin;
select * from t where id = N for update;
--如果行不存在
insert into t values(N,N,N);
--如果行存在
update t set d = N set id = N;commit;

现在出现这个现象:这个逻辑一旦有并发,就会碰到死锁。
在这里插入图片描述

死锁的产生:两个间隙锁不冲突,相互等待行锁

执行流程:

1、session A执行select…for update语句,由于id=9这一行不存在,因此会加上间隙锁(5,10)

2、session B执行select…for update语句,同样会加上间隙锁(5,10)

3、session B插入(9,9,9),被session A的间隙锁锁住,进入等待

4、session A擦汗如·插入(9,9,9),被session B的间隙锁锁住。

InnoDB死锁检测发现了这对死锁关系,然后报错返回了。

所以说间隙锁的引入可能会导致相同的语句锁住更大的范围,从而影响并发度。

间隙锁是在可重复读隔离级别下才会生效的。所以,你如果把隔离级别设置为读提交的话,就没有间隙锁了。 但同时,你要解决可能出现的数据和日志不一致问题,需要把 binlog 格式设置为 row。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css 阴影 效果_CSS阴影效果

css 阴影 效果CSS中的阴影效果 (Shadow Effects in CSS) It is always good to make our web pages stylish and beautiful, web pages that would catch users eyes instantly but one gets confused as to how to style his or her web page. The confusion is quite legit t…

java常见的ClassNotFoundException-----菜鸟学习java

java常见的ClassNotFoundException 1 - java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory 添加包common-logging.jar2 - java.lang.ClassNotFoundException: javax.transaction.Synchronization 添加包jta.jar(hiberante)3 - java.lang.ClassNo…

关于easyui的一些小知识点(1)

让layout布局自动适应浏览器宽度只需要加上fit"true"属性。转载于:https://www.cnblogs.com/haifg/p/3613789.html

《MySQL——加锁规则(待补全,有些没看懂)》

catalog加锁规则等值查询间隙锁非唯一索引等值锁主键索引范围锁非唯一索引范围锁唯一索引范围锁 bug非唯一索引上存在"等值"的例子limit语句加锁关于死锁总结 1、查询过程中访问到的对象才会加锁,而加锁的基本单位是next-key lock(前开后闭&am…

c# 命名空间命名规范_C#中的命名空间

c# 命名空间命名规范C#命名空间 (C# Namespace ) In C# namespaces are used to group similar type of classes. Two classes with same name in different namespaces never conflict to each other. 在C#中,名称空间用于对相似类型的类进…

PHP环境搭建:Windows 7下安装配置PHP+Apache+Mysql环境教程

这两天刚装好Windows 7,碰巧前段时间有朋友问我Windows下如何安装搭建PHP环境,所以打算勤劳下,手动一步步搭建PHP环境,暂且不使用PHP环境搭建软件了,在此详细图解在Windows 7下安装配置PHPApacheMysql环境的教程&#…

《MySQL—— 业务高峰期的性能问题的紧急处理的手段 》

catalog短连接风暴先处理占着连接但是不工作地线程减少连接过程的消耗慢查询性能问题索引没有设计好语句没写好选错索引QPS突增问题短连接风暴 正常的短连接: 执行很少sql语句就断开,下次需要的时候再重连。MySQL建立连接的过程成本很高,包含…

sql 算出下级销售总和_找出总和字符串

sql 算出下级销售总和Description: 描述: This is a standard interview problem to check that the given string is a sum string or not using backtracking. 这是一个标准的面试问题,用于检查给定的字符串是否为总和字符串或不使用回溯。 Problem…

Request 分别获取具有相同 name 属性表单元素值

html 中是允许多个具有相同name属性的元素的&#xff0c;例如 <div> <input name"txtName" id"txtFirstName" type"text" /> <input name"txtName" id"txtMiddleName" type"text" /> <input…

《MySQL——redo log 与 binlog 写入机制》

目录binlog写入机制redo log写入机制组提交机制实现大量的TPS理解WAL机制如何提升IO性能瓶颈WAL机制告诉我们&#xff1a;只要redo log与binlog保证持久化到磁盘里&#xff0c;就能确保MySQL异常重启后&#xff0c;数据可以恢复。 下面主要记录一下MySQL写入binlog和redo log的…

BBIAB的完整形式是什么?

BBIAB&#xff1a;再回来一点 (BBIAB: Be Back In A Bit) BBIAB is an abbreviation of "Be Back In A Bit". BBIAB是“ Be Back in A Bit”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites lik…

字符串:KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组

涉及到字符串的问题&#xff0c;无外乎这样一些算法和数据结构&#xff1a;自动机 KMP算法 Extend-KMP 后缀树 后缀数组 trie树 trie图及其应用。当然这些都是比较高级的数据结构和算法&#xff0c;而这里面最常用和最熟悉的大概是kmp&#xff0c;即使如此还是有相当一部分人也…

WPF CanExecuteChanged

继承ICommand ,RelayCommand命令 1 public class RelayCommand : ICommand2 {3 private readonly Action _execute;4 private readonly Func<bool> _canExecute;5 public event EventHandler CanExecuteChanged;6 public RelayComma…

《MySQL——主备一致性六问六答》

目录备库为什么要设置为只读模式&#xff1f;备库设置为只读&#xff0c;如何与主库保持同步更新&#xff1f;A到B的内部流程如何&#xff1f;binlog内容是什么&#xff1f;row格式对于恢复数据有何好处M-M结构的循环复制问题以及解决方案备库为什么要设置为只读模式&#xff1…

代码管理工具

http://blogs.msdn.com/b/visualstudio/archive/2012/06/11/world-of-samples-at-your-fingertips.aspx转载于:https://www.cnblogs.com/hebeiDGL/archive/2012/09/25/2700961.html

fyi 在邮件里是什么意思_FYI的完整形式是什么?

fyi 在邮件里是什么意思仅供参考&#xff1a;供您参考 (FYI: For Your Information) FYI is an acronym of "For Your Information". It is a widespread internet slang used these days in text messaging, instant messaging, and chatting on Facebook, WhatsApp…

Hyper-V 替换 vmwp

要激活 Hyper-V 下的虚机 最简单的方法是用带证书的vmwp替换掉原来的 带证书的vmwp参见&#xff1a;http://bbs.pcbeta.com/viewthread-1408240-1-1.html 下载后腰替换 先把 Hyper-V 的俩服务停止掉 然后找到 C:\Windows\System32\vmwp.exe 右键--安全 替换掉所有者 然后给自己…

《MySQL——主备切换流程与主备延迟》

目录主备切换主备延迟的原因可靠性优先策略的主备切换流程可用性优先策略的主备切换流程主备切换 主备切换分为主动运维与被动操作。 软件升级、主库所在机器按计划下线为主动运维。 主库所在机器掉电为被动操作。 同步延迟 1、主库A执行完一个事务&#xff0c;写入binlog…

ejb模式_EJB的完整形式是什么?

ejb模式EJB&#xff1a;企业Java Bean (EJB: Enterprise Java Bean) EJB is an abbreviation of Enterprise Java Bean. EJB is one of many Java application programming interfaces (API) for flexible and manageable structuring of Java Platform, Enterprise Edition (J…

Android之PreferenceActivity

http://www.cnblogs.com/wservices/archive/2010/07/08/1773449.html 看到很多书中都没有对PreferenceActivity做介绍&#xff0c;而我正好又在项目中用到&#xff0c;所以就把自己的使用的在这总结一下&#xff0c;也方便日后查找。 PerferenceActivity是什么&#xff0c;看下…