innodb的事务隔离级别是可重复读级别且innodb_locks_unsafe_for_binlog禁用,也就是说允许next-key lock

CREATE TABLE `LockTest` (
   `order_id` varchar(20) NOT NULL,
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   PRIMARY KEY (`id`),
   KEY `idx_order_id` (`order_id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

事务1 事务2

begin

delete from LockTest where order_id =  'D20'

 
 

begin

delete from LockTest where order_id =  'D19'

insert into LockTest (order_id) values ('D20')

 
 

insert into LockTest (order_id) values ('D19')

commit

commit

事务1 执行到insert语句会block住,事务2执行insert语句会提示死锁错误

错误码: 1213
Deadlock found when trying to get lock; try restarting transaction

Execution Time : 00:00:00:000
Transfer Time : 00:00:00:000
Total Time : 00:00:00:000

show engine innodb status 显示死锁信息

------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-04-30 15:01:55 a233b90
*** (1) TRANSACTION:
TRANSACTION 596042, ACTIVE 7 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 10851, OS thread handle 0x2abfb90, query id 251521 10.10.53.122 root update
insert into LockTest (order_id) values ('D20')
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596042 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) TRANSACTION:
TRANSACTION 596041, ACTIVE 19 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 320, 2 row lock(s), undo log entries 1
MySQL thread id 10848, OS thread handle 0xa233b90, query id 251522 10.10.53.122 root update
insert into LockTest (order_id) values ('D19')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596041 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 502 page no 4 n bits 72 index `idx_order_id` of table `test`.`LockTest` trx id 596041 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;

*** WE ROLL BACK TRANSACTION (2)

简单分析上面的场景先删除再插入的sql是hibernage保存集合关联的处理方式。delete语句删除不存在且删除的order_id大于现有表中的所有order_id,所以delete语句会使用next-key锁住(当前最大-无穷大)

lock_id lock_trx_id lock_mode lock_type lock_table lock_index lock_space lock_page lock_rec lock_data
596133:502:4:1 596133 X RECORD `test`.`LockTest` idx_order_id 502 4 1 supremum pseudo-record
596134:502:4:1 596134 X RECORD `test`.`LockTest` idx_order_id 502 4 1 supremum pseudo-record

比较奇怪的是为啥两个事务都拿到了相同区间的(当前最大-无穷大)的X锁。不过换成read-commited级别后就没死锁了。

终于在官方文档找到答案, 区间锁只是用来防止其他事务在区间中插入数据,区间x锁 与区间S锁效果是一样的。也就是说不会因为两个事务都用加相同区间锁而相互等待的

https://dev.mysql.com/doc/refman/5.1/en/innodb-record-level-locks.html

Gap locks in InnoDB are “purely inhibitive”, which means they only stop other transactions from inserting to the gap. Thus, a gap X-lock has the same effect as a gap S-lock.

当两个事务拿到相同区间锁后,就会阻止对方忘区间内做insert操作。所以第一个事务insert会阻塞,第二个事务会提示死锁

innodb next-key lock引发的死锁的更多相关文章

  1. InnoDB的锁机制浅析(五)—死锁场景(Insert死锁)

    可能的死锁场景 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意 ...

  2. zz 关于插入意向间隔锁( insert intention gap lock)产生的死锁问题

    出处: http://www.cnblogs.com/sunss/p/3166550.html 昨天看到一个很有意思的死锁,拿来记录下: 环境:deadlock on 事务隔离级别: read com ...

  3. 关于InnoDB的Next-Key lock

    最近一段时间在准备新员工培训的材料,本来打算介绍介绍概念就OK的,但是既然写了事务的章节,就特别想介绍一下锁,介绍了锁,就忍不住想介绍一下Next-Key Lock. 大家知道,标准的事务隔离级别有R ...

  4. Key lock 的秘密

    研究死锁,或者观察sp_lock,有时候最恼人的莫过于你看到下面研究成果的key lock,但是却不知道究竟是哪个page 哪个row被lock住了: Exec sp_lock:   就说上面的key ...

  5. SQL Server 隐式转换引发的死锁

    在SQL Server的应用开发过程(尤其是二次开发)中可能由于开发人员对表的结构不够了解,造成开发过程中使用了不合理的方式造成数据库引擎未按预定执行,以致影响业务.这是非常值得注意的.这次为大家介绍 ...

  6. mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11

    问题描述:启动MySQL后,出现连接不上,报 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11[root@mysql01 ~]# service ...

  7. index_merge引发的死锁排查

    概述 前几天排查了一个死锁问题,最开始百思不得其解,因为发生死锁的两个事务是单语句事务,语句类型相同(where属性列相同,仅值不同),而且语句都走了相同的索引,但最终确实发生了死锁.通过定位排查发现 ...

  8. 同一张表不同SESSION相互持有对方记录引发的死锁

    锁产生的原因:如果有两个会话,每个会话都持有另一个会话想要的资源,此时就会发生死锁. 同一张表不同SESSION持有不同记录 SQL> create table t1(id int); Tabl ...

  9. oracle大数据量更新引发的死锁问题解决方法及oracle分区和存储过程的思考

    前言 前几天上午在对数据库的一张表进行操作的时候,由于这张表是按照时间的一张统计表,正好到那天没有测试数据了,于是我想将表中所有的时间,统一更新到后一个月,于是对80w条数据的更新开始了.整个过程曲折 ...

随机推荐

  1. ASP.NET MVC入门到精通——数据库仓储

    业务层调用数据层对象,我不想每次都new一个数据层对象,而是在数据层创建一个仓储,统一管理所有的对象调用. 1.在IDAL项目中,新建IDBSession.tt模板   Ctrl+S后自动生成IDBS ...

  2. [C] 如何使用头文件 .h 编译 C 源码

    在 C 语言中,头文件或包含文件通常是一个源代码文件,程序员使用编译器指令将头文件包含进其他源文件的开始(或头部),由编译器在处理另一个源文件时自动包含进来. 一个头文件一般包含类.子程序.变量和其他 ...

  3. 天猫浏览型应用的CDN静态化架构演变(转)

    转自:http://wbj0110.iteye.com/blog/2036613 在天猫双11活动中,商品详情.店铺等浏览型系统,通常会承受超出日常数倍甚至数十倍的流量冲击.随着历年来双11流量的大幅 ...

  4. vc11(vs2012)下编译php源码

    需要原料: vs2012.php源码 1.本机的mingw没搞定,参考网上文章尝试vs2012编译,借助vs2012自带的命令行工具: 需要去bison官网下载bison.exe放在“c:/windo ...

  5. Objective-c官方文档 封装数据属性

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 很多对象需要跟踪信息为了执行他们的任务.一些对象设计模型一个或者多个值.例如NSNumber 类用来保存一个值或者自定义的类有一些属性.有一些对象不 ...

  6. 行逻辑链接的顺序表实现稀疏矩阵的相乘(Java语言描述)

    行逻辑链接,带行链接信息.程序有空指针BUG,至今未解决.还是C/C++适合描述算法数据结构.以后复杂的算法还是改用C/C++吧. 有BUG的代码,总有一天会换成没有BUG的. package 行逻辑 ...

  7. Storm启动流程分析

    1. 客户端运行storm nimbus时,会调用storm的python脚本,该脚本中为每个命令编写一个方法,每个方法都可以生成一条相应的java命令. 命令格式如下:java -server xx ...

  8. [转]了解如何通过reverse_iterator的base得到iterator

    转自:http://blog.csdn.net/shuchao/article/details/3705252 调用reverse_iterator的base成员函数可以产生“对应的”iterator ...

  9. host.conf 文件

    /etc/host.conf文件的作用是设置名称解析时的先后顺序/etc/hosts文件是在使用host解析时,手动的添加的主机记录/etc/relov.conf文件中设置DNS服务器名称以及缺省的域 ...

  10. UEditor富文本WEB编辑器自定义默认值设置方法

    1.在使用UEditor编辑器编写内容时你会发现,当输入的内容较多时,编辑框的边框高度也会自动增加,若希望输入内容较多时以拉框滚动的效果. 方法:找到Ueditor文件根目录下的ueditor.con ...