InnoDB数据库死锁

article/2025/8/26 18:04:37


 

正文

回到顶部

场景描述

在update表的时候出现DeadlockLoserDataAccessException异常 (Deadlock found when trying to get lock; try restarting transaction...)。

回到顶部

问题分析

这个异常并不会影响用户使用,因为数据库遇到死锁会自动回滚并重试。用户的感觉就是操作稍有卡顿。但是监控老是报异常,所以需要解决一下。

回到顶部

解决方法

在应用程序中update的地方使用try-catch。

我自己封装了一个函数,如下。

复制代码
/*** 2016-03-15* linxuan* handle deadlock while update table*/private void updateWithDeadLock(TestMapper mapper, Test record) throws InterruptedException {boolean oops;int retries = 5;do{oops = false;try{mapper.updateByPrimaryKeySelective(record);}catch (DeadlockLoserDataAccessException dlEx){oops = true;Thread.sleep((long) (Math.random() * 500));}finally {}} while(oops == true && retries-- >0);}
复制代码

我用的是mybatis,所以只需将mapper传进函数,如果不用mybatis,需要自己创建并关闭数据库连接。

回到顶部

延伸:数据库死锁

数据库死锁是事务性数据库 (如SQL Server, MySql等)经常遇到的问题。除非数据库死锁问题频繁出现导致用户无法操作,一般情况下数据库死锁问题不严重。在应用程序中进行try-catch就可以。那么数据死锁是如何产生的呢?

InnoDB实现的是行锁 (row level lock),分为共享锁 (S) 和 互斥锁 (X)。

  • 共享锁用于事务read一行。
  • 互斥锁用于事务update或delete一行。

当客户A持有共享锁S,并请求互斥锁X;同时客户B持有互斥锁X,并请求共享锁S。以上情况,会发生数据库死锁。如果还不够清楚,请看下面的例子。

回到顶部

数据库死锁例子

首先,客户A创建一个表T,并向T中插入一条数据,客户A开始一个select事务,所以拿着共享锁S。

复制代码
mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
Query OK, 0 rows affected (1.07 sec)mysql> INSERT INTO t (i) VALUES(1);
Query OK, 1 row affected (0.09 sec)mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i    |
+------+
|    1 |
+------+
复制代码

然后,客户B开始一个新事务,新事务是delete表T中的唯一一条数据。

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)mysql> DELETE FROM t WHERE i = 1;

删除操作需要互斥锁 (X),但是互斥锁X和共享锁S是不能相容的。所以删除事务被放到锁请求队列中,客户B阻塞。

最后,客户A也想删除表T中的那条数据:

mysql> DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

死锁产生了!因为客户A需要锁X来删除行,而客户B拿着锁X并正在等待客户A释放锁S。看看客户A,B的状态:

  • 客户A: 拿着锁S,等待着客户B释放锁X。
  • 客户B: 拿着锁X,等待着客户A释放锁S。

发生死锁后,InnoDB会为对一个客户产生错误信息并释放锁。返回给客户的信息:

ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

所以,另一个客户可以正常执行任务。死锁结束。

参考资料:

http://dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks.html

http://www.xaprb.com/blog/2006/08/03/a-little-known-way-to-cause-a-database-deadlock/



http://chatgpt.dhexx.cn/article/i21SgVqO.shtml

相关文章

mysql数据库死锁原因分析

一、死锁模拟复现 1、当前自己电脑的mysql版本8.0.22 2、数据库的隔离级别--可重复读(默认隔离级别) 3、自动提交关闭 4、表结构,age为非唯一索引,对下面整个案例非常重要 5、 1、事务A执行更新操作,更新成功 2、事务…

处理数据库死锁问题

在实际的项目环境中碰到了如下的问题 Microsoft.Data.SqlClient.SqlException (0x80131904): 事务(进程 ID 98)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。 怀疑是因为数据库查询和修改中产生的死锁问题,造成的上述原因…

数据库死锁:原因和解决办法

理解数据库中的死锁 在数据库的上下文中,死锁是指两个或多个事务无法进行的情况,因为每个事务都在等待另一个事务释放资源。这可以类比为事务的循环链,每个事务都在等待链中的下一个事务释放资源。以下是一个死锁场景的视觉表示:…

Java面试必问:死锁(多线程死锁+数据库死锁)

死锁 接下来从几个方面介绍: 多线程死锁多线程死锁解决办法数据库死锁数据库死锁解决办法 多线程死锁是怎么造成的? 多线程锁定同一资源会造成死锁线程池中的任务使用当前线程池也可能出现死锁 参考连接: https://blog.csdn.net/qq_3506…

MySQL数据库死锁了,该怎么办?一文全解最新教程

文章目录 正文死锁的发生为什么会产生死锁?Insert 语句是怎么加行级锁的?1、记录之间加有间隙锁2、遇到唯一键冲突 如何避免死锁? 之前分享过 MySQL 死锁的文章,然后很多读者对「插入意向锁」认识很迷糊。 大家误以为「插入意向锁…

5 分钟理解数据库死锁

图片来源:网络 文章目录 死锁是如何产生的?如何解决并避免死锁总结 🍺知人者智,自知者明。胜人者有力,胜己者强。知足者富,强行者有志。不失其所者久,死而不亡者寿。——老子 大家好&#xff01…

数据库死锁场景

场景一: 单一线程多次进入子事务发生死锁 问题: 线上问题发生了死锁,但通过死锁日志发现一直在等待查询结果。我们使用的数据库是PGsql,默认的隔离级别是“读已提交”,按理来说查询不会加锁,导致一度被带偏…

数据库常见死锁原因及处理

目录 前言什么是死锁死锁产生的四个必要条件 1. 表锁死锁死锁场景解决方案建议 2. 行锁死锁2.1 两个事务分别想拿到对方持有的锁,互相等待,于是产生死锁死锁场景解决方案 2.2 共享锁转换为排他锁死锁场景解决方案 3. INSERT ... ON DUPLICATE KEY UPDATE…

数据库死锁分析与解决

一、死锁的表现 1、错误信息是:事务(进程 ID)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。 2、错误信息是:事务(进程 ID )与另一个进程被死锁在 锁 | 通信缓冲区 资源上,并且已被选作死锁牺牲品。请重新运行该事务。 二、…

数字 IC 技能拓展(1)Xilinx_Vivado_SDK_2019.1 安装详细教程

引言 工欲善其事必先利其器,而君之“器”尚无,就更别谈“事”了。赶紧!我们需要下载并安装一个 Xilinx Vivado 软件!!接下来就飞速地开始我们的 Xilinx_Vivado_SDK_2019.1 详细安装教程!!&#…

win10安装vivado + vitis 2019.2 教程

win10安装vivado vitis 2019.2 教程 安装包:链接:https://pan.baidu.com/s/1fPlNDzpC0EPXMhOloDyzfA 提取码:1234 网上其他博主的安装教程,比如:vivado2019.2的安装,最后是没有安装上vitis PS端开发软件…

vivado入门教程

vivado入门教程 基本步骤例程实现 第一次写博客,也是第一次使用vivado,自己也在学习之中,欢迎大家的评论啊! 基本步骤 一、新建工程 二、选择工程路径及命名 三、一路next到下图,确定芯片的型号 四、添加源文件 五…

手把手教你安装vivado2015.4开发环境

//vivado2015.4安装教程 //作者:紫菜蛋花汤 //时间:2018.7.8 //版本:V1 准备工作: 1.vivado2015.4安装包 官方下载压缩包文件名:Xilinx_Vivado_SDK_2015.4_1118_2.tar 个人百度云连接:https://pan.ba…

Vivado 2015.4 安装教程(含license)

首先先下载vivado2015.4的压缩文件,可以从网盘里下载: 百度网盘链接:点击链接 下载后解压: 点击xsetup.exe文件 点击Next 点击Next 一定要选择第一个Vivado HL WebPack,不要像图中那样选择第三个,因为第一…

vivado 2017.4安装步骤

目录:windows安装vivado2017.4;虚拟机ubuntu安装vivado 2017.4;ios安装vivado。 一,windows安装vivado2017.4 xilinx官网下载地址为:https://www.xilinx.com/support/download.html 下载完解压后,如图所示…

vivado2019.2安装+license添加教程

vivado2019.2安装license添加教程 注意: 1.电脑的账户名字一定是英文; 2.压缩文件夹有30个G,安装后会更大,需要预留足够的空间。 1.资源链接 百度网盘: https://pan.baidu.com/s/1xEuB-vzoXWpj40fd1wAEFg 密码:tkk1…

[Software]Vivado 2018.2 安装及激活教程

一、安装 1、 解压文件 注:要将压缩文件解压至无中文的路径中。 2、 双击“xsetup.exe”文件,开始安装 3、 不选择新版本,选择继续安装此版本 4、 点击“Next”出现协议,在“I Agree”前都打勾 5、 版本选择,用户可以…

Vivado的下载和安装

本文是自己在安装和使用vivado的一个简单记录。 在安装之前进入官网下载好自己需要版本的安装包,软件安装包比较大,需要花费比较长的一段时间。 vivado官网下载地址 :下载地址 安装好软件后需要使用到license文件,可以去官网申…

Vivado2021.2版本安装教程

Vivado2021.2版本安装教程 2021.2版本提取链接:https://pan.baidu.com/s/12P7twkEVErKmqTmkhTnvMg 提取码:2hyr。 第一步:首先打开解压好的软件,找到xsetup.exe,然后管理员模式运行,出现以下界面,点击Next。…

Vivado安装教程详细版

之前问过大佬,哪个版本的vivado更加稳定,大佬说2017.4,于是俺就安装了一个。 安装步骤: 关闭360等杀毒软件。 下载解压后,双击打开这个xsetup程序: 弹出 点击Continue 三个I Agree全部勾选,…