在使用 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. qtjambi_编译

    ZC: 写文章时间为 20160716 1. 1.1.在 Win7x64中编译不成功,主要原因是 源码中包含的程序generator.exe出现内存错误 ==> 于是,转到 虚拟机XPsp3中编 ...

  2. 使用maven创建项目时报错The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

    Description Resource Path Location Type The superclass "javax.servlet.http.HttpServlet" wa ...

  3. selenium学习笔记(xpath和css定位)

    简单的介绍下xpath和css的定位 理论知识就不罗列了 还是利用博客园的首页.直接附上代码: 这个是xpath #!/usr/bin/env python # -*- coding: utf_8 - ...

  4. selenium学习笔记(webdriver下载配置)

    selenium安装后默认安装firefox可以直接使用,当然可以通过其它浏览器 博主这里整理了:chrome . IE 首先是下载地址 http://docs.seleniumhq.org/down ...

  5. ubuntu14.04搭建Hadoop2.9.0集群(分布式)环境

    本文进行操作的虚拟机是在伪分布式配置的基础上进行的,具体配置本文不再赘述,请参考本人博文:ubuntu14.04搭建Hadoop2.9.0伪分布式环境 本文主要参考 给力星的博文——Hadoop集群安 ...

  6. easyui-textbox高为0

    之前在项目中也遇到过,一段时间没遇到这种问题居然又忘记了,想着还是在博客中记录一下,方便自己记忆,也供大家参考. 大家是否也遇到过easyui-textbox高为0的情况呢 像这样:  用户名:< ...

  7. Ant Design

    https://ant.design/components/form-cn/    (Ant Design of React 中文网) 1.Ant Design of react (相关资料) htt ...

  8. docker 私有registry 配置

    备注:此处使用linux镜像配置仓库 registry 启动步骤 https://hub.docker.com/_/registry/ docker login docker pull registr ...

  9. 几种常见排序算法的C++描述

    基本的排序算法有如下特点: 1.几种容易的算法都是以O(N2)排序的 2.Shell排序编程简单,其也是以O(N2)排序的,在实践中用的很多 3.复杂的排序算法往往都是按照O(NlogN)尽心排序的 ...

  10. 版本工具管理之----git

    如何查看隐藏文件夹: 如果你看不到.git目录,你需要让隐藏的文件可见.具体做法就是打开一个Terminal窗口,输入以下命令: defaults write com.apple.finder App ...