在使用 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. on绑定阻止冒泡失败

    使用zepto库,有如下dom <div id="J_parent"> <a href="#"> <span>点我有惊喜&l ...

  2. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  3. 浅谈 django Models中的跨表

    跨表操作在数据库操作非常常用,虽然其会降低读取数据的性能,但是它能节约数据在硬盘中的占用,优化数据表的结构和各自之间的关系. 在sql中,一般跨表需要用到 join 关键字 select * from ...

  4. python 图像库PIL详解

    PIL详细文档 The most important class in the Python Imaging Library is the Image class, defined in the mo ...

  5. hdu4348区间更新的主席树+标记永久化

    http://acm.hdu.edu.cn/showproblem.php?pid=4348 sb的标记永久化即可,刚开始add和sum没复制过来wa了两发...,操作和原来的都一样,出来单点变成区间 ...

  6. python3 on macos with vscode

    brew install python3 python3 -m pip install pylint python3 -m pip install autopep8 python3 -m pip in ...

  7. ionic2常见问题——启动后白屏问题

    问题描述 app启动后大概有几秒白屏,才会显示首页. 解决方案 图 1-最初config.xml配置 图 2-更改后的splash配置 代码: <preference name="Sh ...

  8. react-router-dom: 重定向默认路由

    <appLayout> <Switch> <Route path='/' exact render={()=> ( <Redirect to={this.ge ...

  9. android Handler的使用(二)

     Handler的使用(二) 一. Handler与线程的关系 Handler在默认情况下,实际上它和调用它的Activity是处于同一个线程的. 例如在Handler的使用(一)的示例1中,虽然 ...

  10. VC6工程因行尾格式无法转换到VS2015

    VC6工程因行尾格式无法转换到VS2015(金庆的专栏 2017.6)参考:https://connect.microsoft.com/VisualStudio/feedback/details/54 ...