在使用 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. 构造函数=default表示什么?

    myClass()=default;//表示默认存在构造函数

  2. DOM元素的位置、尺寸及更多的信息

    一.基本概念 document.documentElement是整个DOM树的根节点,对应的元素就是html.下面将其称作根元素或根节点. document.body,对应的元素是body 二.浏览器 ...

  3. 智课雅思词汇---二十五、形容词后缀-ate-fic-ose-ulent-olent-ous-ulous-y

    智课雅思词汇---二十五.形容词后缀-ate-fic-ose-ulent-olent-ous-ulous-y 一.总结 一句话总结: 1.形容词后缀-ate(determinate)? determi ...

  4. activity启动模式之singleInstance

    activity启动模式之singleInstance 一.简介 Log.d("C2", getTaskId()+"");里面的getTaskId()可以获取a ...

  5. GO学习笔记:函数传值与传指针

    当我们传一个参数值到被调用函数里面时,实际上是传了这个值的一份copy,当在被调用函数中修改参数值的时候,调用函数中相应实参不会发生任何变化,因为数值变化只作用在copy上. 为了验证我们上面的说法, ...

  6. C++(二十一) — 引用概念及本质

     1.引用概念 引用是别名,必须在声明的时候初始化.即:是指一个已定义变量的别名.(一个内存空间,有两个名字都可以操作) 引用:在函数调用时,是变量的别名,不可以单独存在,使用时必须要初始化: 指针: ...

  7. Codeforces Round #448 (Div. 2)C. Square Subsets

    可以用状压dp,也可以用线型基,但是状压dp没看台懂... 线型基的重要性质 性质一:最高位1的位置互不相同 性质二:任意一个可以用这些向量组合出的向量x,组合方式唯一 性质三:线性基的任意一个子集异 ...

  8. C语言之内存四区模型和函数调用模型

      内存四区模型 流程说明1.操作系统把物理硬盘代码load到内存2.操作系统把c代码分成四个区3.操作系统找到main函数入口执行 1.内存四区: 一个由c/C++编译的程序占用的内存分为以下几个部 ...

  9. YCSB benchmark测试cassandra性能——和web服务器测试性能结果类似

    转自:http://www.itdadao.com/articles/c15a531189p0.html http://www.cnblogs.com/bettersky/p/6158172.html ...

  10. Myeclipse快捷键的设置以及默认的编码格式

    设置默认的编码格式