SQL死锁

目录

前言:

分析:

死锁产生的原因:

sql死锁

模拟:

解决办法: (本质:快速筛选或高效处理、以此减少锁冲突)

①大事务拆成小事务,尽可能缩小事务范围

大事务:将多个操作放在一个事务中执行

小事务:将多个操作分成多个小事务,

 ②业务中存在更新前和更新后一模一样的不再执行更新

3、 调整表修改的顺序

4. 索引不当导致的死锁

为什么建索引能有效避免死锁呢?

5、降低并发 

6、重试机制


前言:

使用脚本刷数据时,开多线程经常遇到死锁现象,面试也经常问到,故开此篇

日志错误示例:

### Error updating database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may exist in com/patpat/product/mapper/SaleProductSkuMapper.java (best guess)
### The error may involve com.patpat.product.mapper.SaleProductSkuMapper.updateById-Inline
### The error occurred while setting parameters
### SQL: UPDATE ps_sale_product_sku_XXXXX_30002  SET sku_id=?, product_id=?,    sku_code=?, image=?  WHERE id=?
### Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:271)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(Abs

分析:

死锁产生的原因:

①不可剥夺(只能由占有资源的进程释放)

②循环等待(每个进程在等待其他进程释放,而其他进程也在等待)

③互斥条件 (一个资源只能同时被一个进程使用)

④请求与保持(申请新资源,并还不释放已占有的)

sql死锁

死锁发生的主要原因是这两个事务对表的锁定顺序不一致,先拿到一把锁的事务等待另一把锁,而那一把锁正被另一个事务持有,形成闭环等待。

模拟:

当多个事务同时访问数据库中的数据并且存在竞争条件时,就有可能发生死锁。下面是一个示例,展示了一个可能导致死锁的情况:

假设有两个用户,用户A和用户B,同时执行以下两个事务:

事务1(用户A):

BEGIN TRANSACTION;
UPDATE orders SET status = 'processing' WHERE order_id = 1;
UPDATE products SET stock = stock - 1 WHERE product_id = 1;
COMMIT;

事务2(用户B):

BEGIN TRANSACTION;
UPDATE products SET stock = stock - 1 WHERE product_id = 1;
UPDATE orders SET status = 'processing' WHERE order_id = 1;
COMMIT;

在以上操作中,存在:用户A执行自己的第一条sql,用户B执行自己第一条sql。用户A再准备执行自己的第二条时,却不能执行了,用户B也不能再执行,于是陷入死锁。如下图:

 死锁产生!

(注意总结 此处死锁的特点:① 开启了事务②交叉修改(如果按顺序操作是不是就不会死锁了呢?应该是的))

那么,死锁是2个以上的不同表才能出现死锁吗?不一定

如下:

事务1:
updae  A  set ... where id =1;
updae  A  set ... where id =2;
..

事务2:
update A  set ... where id =2;
update A  set ... where id =1;

因此可以总结:

①同一个表中:在一个事务中对同一表进行两次或多次操作,并且在多线程的情况下有多个这样的事务,这可能会导致死锁。

②不同表中:两个事务操作表的顺序不同,出现锁表交叉循环,导致死锁。

解决办法: (本质:快速筛选高效处理、以此减少锁冲突)

①大事务拆成小事务,尽可能缩小事务范围

大事务:将多个操作放在一个事务中执行

优点:这样可以减少事务的提交和回滚次数,提高性能。

缺点:如果事务过大,涉及到的数据量多,会增加事务持有锁的时间,增加死锁的风险。

小事务:将多个操作分成多个小事务,

优点:每个小事务只涉及少量的数据,尽快释放锁资源。这样可以减少事务持有锁的时间,降低死锁的风险

 ②业务中存在更新前和更新后一模一样的不再执行更新

场景:通过运维拉去mysql日志,查询发现,下面2事务,对表ps_option_value666进行更新操作,查询数据库发现,要更新的数据和想更新的数据,一模一样!

解决方案:在代码层面检查对象内容如果一样,就不更新了!

数据库死锁日志中部分日志:

数据库原有数据:

 数据库死锁日志:

2023-06-15 01:35:18 0x2b170f8877002023-06-15 01:35:18 0x2b170f887700
*** (1) TRANSACTION:
TRANSACTION 15159595386, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 5 row lock(s)
MySQL thread id 506546, OS thread handle 47376231835392, query id 4253348818 172.31.19.109 app_product_0 updating
UPDATE ps_option_value666  SET option_id=6,
value='18-24 Months'  WHERE id=1118
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1236 page no 10 n bits 0 index PRIMARY of table `product_service`.`ps_option_value666` trx id 15159595386 lock_mode X locks rec but not gap waiting
Record lock, heap no 224 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len=4; bufptr=0x2b231cfcf469; hex= 0000045e; asc    ^;;
 1: len=6; bufptr=0x2b231cfcf46d; hex= 00000027a645; asc    ' E;;
 2: len=7; bufptr=0x2b231cfcf473; hex= 940000030237da; asc      7 ;;
 3: len=4; bufptr=0x2b231cfcf47a; hex= 00000000; asc     ;;
 4: len=4; bufptr=0x2b231cfcf47e; hex= 00000006; asc     ;;
 5: len=12; bufptr=0x2b231cfcf482; hex= 31382d3234204d6f6e746873; asc 18-24 Months;;
 6: SQL NULL;
 7: len=8; bufptr=0x2b231cfcf48e; hex= 0000000000001840; asc        @;;
 8: len=4; bufptr=0x2b231cfcf496; hex= 5b061db0; asc [   ;;
 9: len=4; bufptr=0x2b231cfcf49a; hex= 5f6df00d; asc _m  ;;
 10: len=0; bufptr=0x2b231cfcf49e; hex= ; asc ;;

*** (2) TRANSACTION:
TRANSACTION 15159595381, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1136, 6 row lock(s)
MySQL thread id 506549, OS thread handle 47373393610496, query id 4253348825 172.31.45.125 app_product_0 updating
UPDATE ps_option_value666  SET option_id=6,
value='4-5 Years'  WHERE id=1446
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 1236 page no 10 n bits 0 index PRIMARY of table `product_service`.`ps_option_value666` trx id 15159595381 lock_mode X locks rec but not gap
Record lock, heap no 226 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len=4; bufptr=0x2b231cfcf4e0; hex= 00000460; asc    `;;
 1: len=6; bufptr=0x2b231cfcf4e4; hex= 00000027a645; asc    ' E;;
 2: len=7; bufptr=0x2b231cfcf4ea; hex= 940000030237f6; asc      7 ;;
 3: len=4; bufptr=0x2b231cfcf4f1; hex= 00000000; asc     ;;
 4: len=4; bufptr=0x2b231cfcf4f5; hex= 00000006; asc     ;;
 5: len=9; bufptr=0x2b231cfcf4f9; hex= 352d36205965617273; asc 5-6 Years;;
 6: SQL NULL;
 7: len=8; bufptr=0x2b231cfcf502; hex= 0000000000002440; asc       $@;;
 8: len=4; bufptr=0x2b231cfcf50a; hex= 5b061dbf; asc [   ;;
 9: len=4; bufptr=0x2b231cfcf50e; hex= 5f6df00d; asc _m  ;;
 10: len=0; bufptr=0x2b231cfcf512; hex= ; asc ;;

[bitmap of 256 bytes in hex: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ]
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 1236 page no 12 n bits 0 index PRIMARY of table `product_service`.`ps_option_value666` trx id 15159595381 lock_mode X locks rec but not gap waiting
Record lock, heap no 66 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
 0: len=4; bufptr=0x2b231cf95154; hex= 000005a6; asc     ;;
 1: len=6; bufptr=0x2b231cf95158; hex= 00000027a645; asc    ' E;;
 2: len=7; bufptr=0x2b231cf9515e; hex= 940000030a0a02; asc        ;;
 3: len=4; bufptr=0x2b231cf95165; hex= 00000000; asc     ;;
 4: len=4; bufptr=0x2b231cf95169; hex= 00000006; asc     ;;
 5: len=9; bufptr=0x2b231cf9516d; hex= 342d35205965617273; asc 4-5 Years;;
 6: SQL NULL;
 7: len=8; bufptr=0x2b231cf95176; hex= 0000000000002240; asc       "@;;
 8: len=4; bufptr=0x2b231cf9517e; hex= 5b061fd6; asc [   ;;
 9: len=4; bufptr=0x2b231cf95182; hex= 5f6df00d; asc _m  ;;
 10: len=0; bufptr=0x2b231cf95186; hex= ; asc ;;

*** WE ROLL BACK TRANSACTION (2)

3、 调整表修改的顺序

按照同一顺序获取多个锁,释放锁时反序释放。这可以避免不同事务交叉锁定导致死锁。

场景:项目中有以下3个脚本,分别:

事务1控制的脚本:

出现交叉,且在两个事务中循环。如果业务允许,则

4. 索引不当导致的死锁

为什么建索引能有效避免死锁呢?

1.为了减少事务持有锁的时间,以此来降低死锁的可能性。

2、避免不同事务对相同的数据行进行锁定,从而减少锁竞争与死锁。(如:对username字段创建普通索引,对email字段创建唯一索引)

5、降低并发 

如果性能允许,自然是单个线程,相当于单个事务在执行,那肯定没死锁!这个就看代码性能和业务允许不允许了

6、重试机制

如果发生死锁,重试可能就好了哇 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/32955.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MOOC 测验】第5章 链路层

1、局域网的协议结构一般不包括( ) A. 数据链路层B. 网络层C. 物理层D. 介质访问控制层 逻辑链路控制子层、介质访问控制子层、物理层 2、下列关于二维奇偶校验的说法,正确的是( ) A. 可以检测和纠正双比特差错B…

【CVRP测评篇】 算法性能如何?来测!

我跨越了2100015秒的距离,为你送上更全面的算法性能评测。 目录 往期优质资源1 CVRP数据集2 实验准备2.1 计算机配置2.2 调参方法2.3 参数设定2.4 实验方法 3 实验结果3.1 最优解统计3.1.1各数据集上的算法性能对比3.1.2 求解结果汇总3.1.3小结一下3.1.4 还有话说 3…

【软考网络管理员】2023年软考网管初级常见知识考点(10)- 网际协议IP及IPV6,IPV4详解

涉及知识点 分类的IP地址,子网划分,CIDR和路由汇聚,IPV4数据报格式,IPV6协议,软考网络管理员常考知识点,软考网络管理员网络安全,网络管理员考点汇总。 原创于:CSDN博主-《拄杖盲学…

剑指 Offer 68 - II. 二叉树的最近公共祖先 / LeetCode 236. 二叉树的最近公共祖先(搜索与回溯)

题目: 链接:剑指 Offer 68 - II. 二叉树的最近公共祖先;LeetCode 236. 二叉树的最近公共祖先 难度:中等 上一题博客:剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 / LeetCode 235. 二叉搜索树的最近公共祖先&#xf…

SSH远程直连Docker容器

文章目录 1. 下载docker镜像2. 安装ssh服务3. 本地局域网测试4. 安装cpolar5. 配置公网访问地址6. SSH公网远程连接测试7.固定连接公网地址8. SSH固定地址连接测试8. SSH固定地址连接测试 转载自cpolar极点云文章:SSH远程直连Docker容器 在某些特殊需求下,我们想ssh…

机器学习李宏毅学习笔记34

文章目录 前言一、Knowledge distillation二、Parameter quantization三、Architecture design四、Dynamic computation总结 前言 神经网络压缩(二)其他方法 一、Knowledge distillation 先train一个大的network叫做teacher network,小的ne…

Vue3:计算属性、监听器

computed 计算属性 计算属性是指 基于现有状态派生 (演变) 出新的状态,现有状态发生变化,派生状态重新计算。 computed 接收回调函数作为参数,基于回调函数中使用的响应式数据进行计算属性的创建,回调函数的返回值就是基于现有状态…

壳牌小程序笔记

壳牌加油站 uni-app-基础-day01 概览 为什么要学uni-app? 现在很多中小型公司,都有自己的小程序项目,然后开发小程序就会用到uni-app。 uni-app没有诞生之前,怎么写小程序 使用原生微信小程序这个框架去开发? 只…

解析vcruntime140.dll文件,缺失了要怎么去修复?

在计算机的世界中,vcruntime140.dll是一个重要的动态链接库文件。然而,有时候这个文件可能会引发一系列问题,影响应用程序的正常运行。如果你缺少了vcruntime140.dll,那么你的程序就会打不开,今天我们一起来聊聊vcrunt…

鸟类识别Python,基于TensorFlow卷积神经网络【实战项目】

一、介绍 鸟类识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Django框架,开发网页端操作平台,…

Linux Ubuntu man文档的图文安装教程

文章目录 前言man文档的起源man文档的安装man文档的使用总结 前言 当提及"man文档"时,通常是指Unix和类Unix系统中的手册页(man page),因为Linux是在Unix的基础上发展而来的操作系统,所以我们的Linux也有ma…

IIS安装localhost显示下载,urlrewrite设置

1.取消ftp服务勾选 2. ping localhost ping 127.0.0.1 如果显示 ::1 则需要禁用ipv6 在注册表 找到并单击下面的注册表子项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\ 双击“DisabledComponents”以修…

【机器学习】sklearn数据集的使用,数据集的获取和划分

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 sklearn数据集 二、安装sklearn二、获取数据集三、…

从电源 LED 读取智能手机的秘密?

研究人员设计了一种新的攻击方法,通过记录读卡器或智能手机打开时的电源 LED,使用 iPhone 摄像头或商业监控系统恢复存储在智能卡和智能手机中的加密密钥。 众所周知,这是一种侧信道攻击。 通过密切监视功耗、声音、电磁辐射或执行操作所需…

STC单片机存储器介绍和使用

STC单片机存储器介绍和使用 🌿STC15F2K60S2系列内部结构框图 🌿STC12C5A60S2系列内部结构框图 📑程序存储器(ROM/Flash) 🔖STC单片机ROM容量大小可以根据其型号和命名规则了解到。 🌿STC15

WiSA Technologies开始接受WiSA E多声道音频开发套件的预订

美国俄勒冈州比弗顿市 — 2023年6月13日 — 为智能设备和下一代家庭娱乐系统提供沉浸式无线声效技术的领先供应商WiSA Technologies股份有限公司(NASDAQ股票代码:WISA)宣布:该公司现在正在接受其WiSA E开发套件的预订。WiSA E使用…

【深度学习】6-1 卷积神经网络 - 卷积层

卷积神经网络(Convolutional Neural Network,CNN)。 CNN 被用于图像识别、语音识别等各种场合,在图像识别的比赛中,基于深度学习的方法几乎都以 CNN 为基础。 首先,来看一下 CNN 的网络结构,了解 CNN 的大致框架。CNN…

macOS编译开源全景拼接库OpenPano

1. 准备工具 clang与cmake 如果要处理png文件要下载安装libjpeg 安装相当依赖: brew install gnu-sed brew install libjpeg brew install eigen brew install libomp2.克隆源码 git clone --recursive https://github.com/ppwwyyxx/OpenPano.git 3.编译 mkdir build cd …

力扣 404. 左叶子之和

题目来源:https://leetcode.cn/problems/sum-of-left-leaves/description/ C题解1:递归法,前序遍历。 1. 确定输入参数:当前节点,左叶子的和; 2. 确定终止条件:空节点时返回; 3. …

Java的Stream流详细讲解

一.Stream 是什么 Stream是Java 8新增的重要特性, 它提供函数式编程支持并允许以管道方式操作集合. 流操作会遍历数据源, 使用管道式操作处理数据后生成结果集合, 这个过程通常不会对数据源造成影响。 ​ 同时stream不是一种数据结构,它只是某种数据源的一个视图&…