MySQL error : Deadlock found when trying to get lock; try restarting transaction

在使用 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 会回滚一个影响最小的事务(直接破坏了上面的第2点,这个事务就成为了 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解析

原文地址:https://www.cnblogs.com/huangzejun/p/8818317.html

时间: 2024-08-30 12:30:26

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

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

我在update数据库的时候出现的死锁 数据库表死锁 这是在网上看到的文章:: 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住). 举个例子: 假设有个表单products ,里面有id跟name二个栏位,id是主键. 例1: (明确指定主键,并且有此笔资料,row lock) SELECT * FROM products WHERE

Deadlock found when trying to get lock; try restarting transaction

1.错误描述 [ERROR:]2015-06-09 16:56:19,481 [抄送失败] org.hibernate.exception.LockAcquisitionException: error executing work at org.hibernate.dialect.MySQLDialect$1.convert(MySQLDialect.java:451) at org.hibernate.exception.internal.StandardSQLExceptionConver

MYSQL ERROR

mysql出错了以前往往靠猜.有了这张表一查就出来了.方便不少.特共享于众 1005创建表失败 1006创建数据库失败 1007数据库已存在创建数据库失败 1008数据库不存在删除数据库失败 1009不能删除数据库文件导致删除数据库失败 1010不能删除数据目录导致删除数据库失败 1011删除数据库文件失败 1012不能读取系统表中的记录 1020记录已被其他用户修改 1021硬盘剩余空间不足请加大硬盘可用空间 1022关键字重复更改记录失败 1023关闭时发生错误 1024读文件错误 1025

MySQL Error Codes MYSQL的错误代码

OS error code 1: Operation not permitted OS error code 2: No such file or directory OS error code 3: No such process OS error code 4: Interrupted system call OS error code 5: Input/output error OS error code 6: No such device or address OS error code

Mac下解决mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

Maybe updating the package the updater overwrote the root password. To restore it: Stop mysqld deamons. $ sudo service mysqld stop Go to mysql/bin directory $ cd /usr/bin Start a mysql deamon with this option: $ sudo mysqld_safe --skip-grant-tables O

MySQL ERROR 1878 解决办法

MySQL ERROR 1878报错解决办法 错误重现 Part1:大表修改字段 mysql> ALTER TABLE `erp` -> ADD COLUMN `eas_status`  tinyint(3) unsigned  NOT NULL DEFAULT 0 ' AFTER `totalprice`; ERROR 1878 (HY000): Temporary file write failure. mysql> \q 这里可以看到,添加字段的时候爆出了1878错误. Part2

[mysql]ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value

From: http://m.blog.csdn.net/blog/langkeziju/13511411 我的MySQL版本为5.6.14版本,是二进制包安装的(虽然是二进制包安装的,但是以下问题同样适用于源码安装包安装的MySQL) 今天在我的测试库上添加一个新用户,报错: [[email protected] ~]$ mysql -uroot -p123456 Warning: Using a password on the command line interface can be in

Mysql,ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'

ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql' 刚在服务器上装上mysql,发现以root加密码的方式总是登录不了,而直接输入mysql则直接就可以登录了.或者以mysql –u root方式可以登录,但是实习上登录上去也是一个空用户(''@'localhost'),不是root用户,看不了其他数据库. 干货,删除空用户方法 1.关闭mysql service mysqld stop 或者

Django syncdb mysql error on localhost -> (1045, "Access denied for user 'ODBC'@'localhost')

环境:WINDOWS系统 将数据库配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': 'localhost', 'PORT': 3306, 'NAME': 'yunwei', 'USERNAME': 'root', 'PASSWORD': 'mysql', } } 改为 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql',