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

article/2025/8/26 18:07:00

目录

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

前言

数据库是一个多用户使用的共享资源,当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并发控制的一个非常重要的技术。在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严重影响应用的正常执行。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

什么是死锁

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程。

死锁产生的四个必要条件

•互斥条件:某段时间内,一个资源一次只能被一个进程访问。

•请求和保持条件:进程A已经拥有至少一个资源,此时又去申请其他资源,而该资源又正在被进程使用,此时请求进程阻塞,但对自己已经获得的资源保持不放。

•不剥夺条件:进程已获得的资源在未使用完不能被抢占,只能在自己使用完时由自己释放。

•环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

1. 表锁死锁

死锁场景

一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。

解决方案

这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。

建议

仔细分析程序的逻辑,对于数据库的多表操作时,尽量避免同时锁定两个资源,如必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。(如操作A和B两张表时,总是按先A后B的顺序处理。)

2. 行锁死锁

2.1 两个事务分别想拿到对方持有的锁,互相等待,于是产生死锁

死锁场景

解决方案

  1. 在同一个事务中,尽可能做到一次锁定所需要的所有资源;
  2. 按照 id 对资源排序,然后按顺序进行处理。

2.2 共享锁转换为排他锁

死锁场景

事务A 查询一条纪录,然后更新该条纪录;此时事务B 也更新该条纪录,这时事务B 的排他锁由于事务A 有共享锁,必须等A 释放共享锁后才可以获取,只能排队等待。事务A 再执行更新操作时,此处发生死锁,因为事务A 需要排他锁来做更新操作。但是,无法授予该锁请求,因为事务B 已经有一个排他锁请求,并且正在等待事务A 释放其共享锁。

事务A

-- 共享锁,1
select * from dept where deptno=1 lock in share mode;
-- 排他锁,3
update dept set dname='java' where deptno=1;

事务B

-- 由于1有共享锁,没法获取排他锁,需等待,2
update dept set dname='Java' where deptno=1;

解决方案

使用乐观锁进行控制。乐观锁机制避免了长事务中的数据库加锁开销,大大提升了大并发量下的系统性能。需要注意的是,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。

3. INSERT … ON DUPLICATE KEY UPDATE产生death lock死锁

死锁场景

insert … on duplicate key 在执行时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,如果返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。
在这里插入图片描述

解决方案

尽量不对存在多个唯一键的table使用该语句

https://blog.csdn.net/qq_16681169/article/details/74784193
https://blog.csdn.net/weixin_42201180/article/details/126447408
概述:https://blog.csdn.net/qq_34107571/article/details/78001309 INSERT
… ON DUPLICATE KEY UPDATE产生死锁原理:https://blog.csdn.net/pml18710973036/article/details/78452688


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

相关文章

数据库死锁分析与解决

一、死锁的表现 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全部勾选,…

Vivado 2018.3 安装步骤及 license 获取

本文的主要内容是介绍 Vivado 2018.3 版本的安装步骤及其 license 的获取与加载。 首先下载安装包,将其在没有中文的路径下解压。注意在解压前最好关闭电脑的杀毒软件,防止某些文件被拦截或者删除! 解压完成后打开文件夹,在最底部…

Vivado的安装以及使用_入门

Vivado的安装以及使用 零. Vivado简要介绍 Vivado是FPGA厂商赛灵思提供的一款EDA(Electronic Design Automation)工具. 在电子设计自动化方面, 其主要提供了四种功能: RTL代码编写, 功能仿真, 综合(synthesis)以及实现(implementation). 其中, RTL代码…

Vivado安装—Xilinx design tool already exists for 2019.1,specify a different program program group entr

V i v a d o 重 新 安 装 出 现 问 题 ? {\color{Red}Vivado重新安装出现问题?} Vivado重新安装出现问题? V i v a d o 重 新 安 装 出 现 问 题 ? {\color{Red}Vivado重新安装出现问题?} Vivado重新安装出现问题&…

vivado2017.4安装教程

安装前先关闭杀毒软件和360卫士,注意安装路径不能有中文,存放安装包的路径最好也不要有中文。 1、解压安装包到当前文件夹 2、运行安装程序。 3、提示下载最新的版本,不要下载,点击Continue,然后点击next。 4、点击I Agree&#x…

vivado快速下载及解压安装教程

vivado快速下载及解压安装教程 一,登录中文版官网 网址 https://china.xilinx.com link 滑动至页面下方产品支持类目点击下载与许可 选择想要下载的版本,初学者建议下载和所要用的教程视频一致的版本或每一年的最后一版最为稳定。 如要下载更早的版本…

FPGA学习——Vivado2017.4安装教程

为方便大家正常学习,提供了Vivado2017.4软件的安装及破解教程,供大家参考。 1、Vivado2017.4安装包下载解压完成后,如下图所示,Linux系统执行蓝色框线(xsetup),Windows系统双击执行红色框线&am…

Xilinx_Vivado_2019.1下载和安装教程

一、vivado2019.1下载和安装教程 1、首先要下载安装包,建议直接在Xilinx官网下载:https://www.xilinx.com/support/download.html。选择我们需要安装的安装包(其他版本也是这样,需要选择支持所有OS的安装包)&#xff…

Vivado18.3的安装 安装教程

本文内容学习自【ALINX】FPGA ZYNQ视频教程——AX7010/AX7020教程——基础部分 1.Vivado18.3的下载 Vivado18.3是18年的最后一个版本,正常来讲每年的最后一个版本即为相对稳定的版本。 百度网盘:https://pan.baidu.com/s/1PiQO1BeLSZNFn_BrqanyFw 提取码&#x…