在使用 MySQL 时,我们有时会遇到这样的报错:“Deadlock found when trying to get lock; try restarting transaction”。

14.5.5.3 How to Minimize and Handle Deadlocks 中有这样一句话:

Deadlocks are not dangerous. Just try again.

死锁不危险,重试一下就行。

实际上这个建议非常实用。

我们回顾一下死锁发生的四个条件:

  1. 资源的独占性(在某一时刻,最多只能被一个事务访问);
  2. 请求与保持(事务获取到锁后,不会主动释放);
  3. 不可剥夺(事务无法获取另一个事务拥有的锁);
  4. 循环等待(即事务 A 获取到锁 Lock1,等待 Lock2,同时事务 B 获取到锁 Lock2,等待 Lock1,此时,事务 A 和 B 循环等待对方释放各自需要的锁)。

值得注意的是,InnoDB 在绝大部分错误发生时都不会回滚(如:等待锁超时不会回滚);

只有一个例外,那就是发生死锁时,InnoDB 会回滚一个影响最小的事务(直接破坏了上面的第 3 点,这个事务就成为了 victim)。此时我们只要重试一下这个 victim 事务,那么,所有的事务都会成功提交。

同时,14.5.5.3 How to Minimize and Handle Deadlocks 中另一段话很重要:

InnoDB uses automatic row-level locking. You can get deadlocks even in the case of transactions that just insert or delete a single row. That is because these operations are not really “atomic”; they automatically set locks on the (possibly several) index records of the row inserted or deleted.

insert / delete 一行也可能引发死锁。

因为这些操作不是原子性的,它们在执行中会加 index record lock。

例子很好构造。

比如有一张表:create table t1 (id int PRIMARY KEY, name char(20) key);

有两个 session 并发:

session 1:

insert into t1 (id, name) values(5, 'Branden');

session 2:

select * from t1 where name > ‘B’ and id >3;

session1 访问 name>'B',会在 Ben、Bob上加 X 锁,并且在 Alex 与 Ben、Ben 与 Bob、Bob 与 Cathy 间加 Gap lock,在聚簇索引 id 为 1、3上加X锁;接下来要获取聚簇索引上 id 为 6、7的 X 锁,以及 (3, 6)、(6, 7)间的 gap lock。

session2 先获取聚簇索引上(3, 6)间的 gap lock;接下来尝试获取 name 索引上(Ben, Bob)、(Bob, Cathy)间的 gap lock。

最后发生死锁。

怎么消除呢?让 select 中 where 子句先访问 id ,再访问 name。

可以阅读这篇文章:http://hedengcheng.com/?p=771#_Toc374698321。

另外,有必要了解各种语句需要的锁:14.5.3 Locks Set by Different SQL Statements in InnoDB

参考资料:

MySQL 5.7 Reference Manual:

14.5.2.3 Consistent Nonlocking Reads

14.5.2.4 Locking Reads

14.5.5 Deadlocks in InnoDB

Stack Overflow:

How to avoid mysql 'Deadlock found when trying to get lock; try restarting transaction'

Working around MySQL error “Deadlock found when trying to get lock; try restarting transaction”

理解innodb的锁(record,gap,Next-Key lock)

MySQL InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析

MySQL error : Deadlock found when trying to get lock; try restarting transaction的更多相关文章

  1. mysql报ERROR:Deadlock found when trying to get lock; try restarting transaction(nodejs)

    1 前言 出现错误 Deadlock found when trying to get lock; try restarting transaction.然后通过网上查找资料,重要看到有用信息了. 错 ...

  2. Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

    我在update数据库的时候出现的死锁 数据库表死锁 Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackExcept ...

  3. MySql 更新死锁问题 Deadlock found when trying to get lock; try restarting transaction

    文章导航-readme MySql 更新死锁问题 Deadlock found when trying to get lock; try restarting transaction 1.场景 //t ...

  4. mysql - InnoDB存储引擎 死锁问题( Deadlock found when trying to get lock; try restarting transaction )

    刚刚向数据库插入数据的时候出现了这么一段错误 Deadlock found when trying to get lock; try restarting transaction 主要原因(由于无法使 ...

  5. Deadlock found when trying to get lock; try restarting transaction

    1.错误描述 [ERROR:]2015-06-09 16:56:19,481 [抄送失败] org.hibernate.exception.LockAcquisitionException: erro ...

  6. 1213 - Deadlock found when trying to get lock; try restarting transaction

    1213 - Deadlock found when trying to get lock; try restarting transaction 出现这个原因要记住一点就是:innodb的行锁 和解 ...

  7. mysql死锁com.mysql.cj.jdbc.exception.MYSQLTransactionRollbackException Deadlock found when trying to get lock;try restarting transaction

    1.生产环境出现以下报错 该错误发生在update操作中,该表并未建立索引,也就是只有InnoDB默认的主键索引,发生错误的程序是for循环中update. 什么情况下会出现Deadlock foun ...

  8. 数据库死锁的问题,Deadlock found when trying to get lock; try restarting transaction at Query.formatError

    场景: 应用刚上线排除大批量请求的问题 线上多次出现的Deadlock found when trying to get lock错误 代码: async batchUpdate(skus, { tr ...

  9. MySQL遇到Deadlock found when trying to get lock,解决方案

    最近遇到一个MYSQL update语句出现Deadlock found when trying to get lock的问题,分析一下原因. 什么情况下会出现Deadlock found when ...

随机推荐

  1. DevExpress组件之——TreeList组件

    由于是第一次接触到第三方控件DevExpress中的TreeList,对其进行了进一步的研究,采用递归算法实现.做下自己熟悉第三方控件的整个过程,为和我一样处理于起步阶段的同仁们提供个参考,以下为最终 ...

  2. Hibernate -- Session的主键生成策略

    *缓存:集合--集合放置到内存中       *  只要session存在 session的一级缓存肯定存在.       *当执行查询时,以oid为oid=1条件到session的一级缓存中查找oi ...

  3. Angularjs注入拦截器实现Loading效果

    angularjs作为一个全ajax的框架,对于请求,如果页面上不做任何操作的话,在结果烦回来之前,页面是没有任何响应的,不像普通的HTTP请求,会有进度条之类. 什么是拦截器? $httpProvi ...

  4. powmock

    Verify 方法是否调用 Ve ri fy 核实 万花筒 瑞雪 发大财 Local Variable 局部变量@RunWith 运行器@PrepareForTest 提前准备 有返回值测试 void ...

  5. C++中GB2312字符串和UTF-8之间的转换

    在编程过程中需要对字符串进行不同的转换,特别是Gb2312和Utf-8直接的转换.在几个开源的魔兽私服中,很多都是老外开发的,而暴雪为了能 够兼容世界上的各个字符集也使用了UTF-8.在中国使用VS( ...

  6. Appium移动自动化测试(三)--自动化测试demo

    使用java语言编写并实现自动化测试实例 前面我已经搭建好了appium所需要的环境,本文我以系统自带的计算器app为测试对象,进行学习. 一.将测试机与PC连接 本人使用的是Android模拟器,测 ...

  7. 《Advanced Bash-scripting Guide》学习(一):对一个增强和广义的删除logfile的脚本的理解

    本文所选的例子来自于<Advanced Bash-scripting Gudie>一书,译者 杨春敏 黄毅 cleanup:一个增强和广义的删除logfile的脚本 #!/bin/bash ...

  8. Codeforces Round #299 (Div. 2)D. Tavas and Malekas

    KMP,先预处理按每个节点标记,扫一遍更新每个匹配位置,最后kmp判断是否有重合而且不相同的地方 注意处理细节,很容易runtime error #include<map> #includ ...

  9. 如何退出telnet

    ctrl键+ENter键 然后输入 进入telnet 命令 quit

  10. static-静态类型

    1.基本概念 好像没什么概念. 2.作用 主要是两个:隐藏和保持值 01.隐藏 当在一个文件中定义了一个static全局变量,则该变量对该文件是可见的,对其他的文件不可见,也就减少了变量冲突的问题. ...