SQL死锁

news2024/11/23 6:56:40

前言:

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

日志错误示例:

### 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_magic_t_grobal_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也不能再执行,于是陷入死锁。如下图:

 死锁产生!

解决办法: 

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

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

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

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

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

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

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

场景:通过运维拉去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)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tplink企业版开启ipv6

Tplink企业版开启ipv6 1、登录路由器 路由器的默认地址一般为:192.168.0.1,登录成功后如下图: 2、WAN设置ipv6 wan是设置启用ipv6模式,如果这里无法启用,主要是因为“接口模式”中启用了桥接模式,可以关闭…

多线程详解

多线程详解 Process和Thread 程序是指令和数据的有序结合,其本身没有任何运行的含义,是一个静态的概念 进程是执行程序的一次执行过程,是一个动态的概念,是系统资源分配的单位 通常在一个进程中可以包含若干个线程。线程是CPU调…

(数组) 922. 按奇偶排序数组 II ——【Leetcode每日一题】

❓922. 按奇偶排序数组 II 难度:简单 给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。 对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时&#xff0c…

开发语言的更新换代,都是为了更好地提高生产力,Kotlin也是如此~

作为一名Android开发,学习Kotlin是很有必要的。以下是一些原因: 1.Kotlin是官方支持的语言。 在2017年Google宣布支持Kotlin作为官方开发语言后,Kotlin已成为Android生态系统的重要组成部分。此举表明Kotlin的发展前景非常广阔,…

uniapp兼容多pda扫描扫码

前景 网上有现成的针对单个pda扫码录入的代码,但是公司的需求是在多个不同厂商pda上运行,这就会导致不同的pda默认的广播动作和广播标签不一致的情况,目前也没有获取这俩字段的api。 单个pda扫描扫码代码 先创建一个scanCode.js的文件 le…

UnoCSS给了我一个不用tailwindcss的理由

相同的原由 & 前言 如果你没有听说过 tailwindcss 或者 unocss,请先 return 先去了解一下😝。 开发上:可能为你甚至你们的前端团队节省很多写样式的时间,也能让你或者你们的项目开发体验有很大提升生产上:你们的…

VS2013创建一个MFC工程的步骤

目录 1、新建项目,选择”MFC应用程序“; 2、应用程序类型,选择“基于对话框”; 3、对话框的标题,默认是和项目的名字一致,按需修改; 4、高级功能,可以保持默认; 5、…

一个女测试工程师的大厂日常

今天给大家分享两个朋友的故事,他们分别在国内两家顶尖的互联网大厂,一个在头条,一个在蚂蚁。 头条的故事 头条的主人公,在入职后的一年里,晚上十点半下班是比较早了,基本上都是十一点半左右下班&#xff…

低成本开发专属小程序支持自定义开发设计

传统定制开发小程序成本高,还需要不断地沟通和交流才能一步步地去实现你想要的功能和效果,那么除了传统的定制开发小程序外,用户其实还可以选择使用模板开发小程序,不仅能实现小程序的所有基础功能,还不用编程维护和开…

进程的描述与控制

文章目录 前趋图和程序执行前趋图程序顺序执行程序并发执行 进程引入目的进程的描述进程的定义进程的特征进程的基本状态与转换挂起操作和进程状态的转换挂起操作引入引入挂起操作后进程3个基本状态间的转换引入挂起操作后进程5个基本状态间的转换进程管理中的数据结构OS中用于…

antdb-upgrade大版本升级介绍

antdb-upgrade pg_upgrade 是postgresql 大版本升级的得力工具。 数据库系统数据部分通过 new version的pg_upgrade自动升级完成数据库用户数据部分,主要有两种用法: 使用pg_upgrade copy物理拷贝方式升级(非copy to/copy from逻辑拷贝)。使用pg_upgra…

内网渗透—隧道搭建SPP与NPS内网穿透

内网渗透—隧道搭建&SPP与NPS内网穿透 1. 前言2. SPP2.1. SPP代理通信2.1.1. 服务端配置2.1.2. 客户端配置2.1.3. CS设置2.1.3.1. 设置生成的监听器2.1.3.2. 设置监听的监听器 2.1.4. 执行效果 2.2. SPP隧道建立2.2.1. 服务端设置2.2.2. 客户端配置2.2.3. CS设置2.2.3.1. 设…

Mybatis学习笔记三

目录 一、MyBatis的缓存1.1 MyBatis的一级缓存1.2 MyBatis的二级缓存1.3 二级缓存的相关配置1.4 MyBatis缓存查询的顺序1.5 整合第三方缓存EHCache(了解) 二、MyBatis的逆向工程2.1 创建逆向工程的步骤2.2 简单使用查询增改 三、 分页插件3.1 分页插件使…

Endnote解决文章题目Title大小写问题,以及专有名词保持全部大写

在写毕业论文或综述类文章时,需要添加大量参考文献(100左右或更多),而每个期刊的要求是不一样的,因此手动输入或修改参考文献的格式是愚蠢的(狗头保命),所以需要强大的endnote来进行…

一篇博客搞定C++11之Lambda表达式(附案例代码+解析)

Lambda表达式 1.lambda表达式语法2.捕获列表说明3.lambda表达式实现原理4.具体案例5.总结 1.lambda表达式语法 ambda表达式的语法非常简单,具体定义如下: [ captures ] ( params ) specifiers exception -> ret { body } 先不用急于解读这个定义&…

面向对象内部类

概念 将一个类 A 定义在另一个类 B 里面,里面的那个类 A 就称为内部类 (InnerClass),类 B 则称为外部类(OuterClass) 根据内部类声明的位置(如同变量的分类),我们可以分…

首次使用云服务器搭建网站(二)

书接上文,我们已经完成了服务器的租赁,宝塔面板的下载与安装。 接下来我们将正式开始网站搭建。 一、网站创建 点击网站、添加站点 输入网站域名、数据库选择MySQL数据库,选择utf8,数据库账号密码会自动生成。无论你要创建什么样…

【linux网络配置】多个网卡一起使用,一个网卡连内网,一个网卡连外网

一、问题背景 因为有一个工作站在内网中,但是没有办法联网(校园网账户有限)。 虽然工作站没有联网,但是我仍然可以通过局域网远程控制工作站,使其访问校园网验证页面实现上网。 当给工作站安装软件或依赖项时&#…

SpringBoot配置文件application.properties的理解

一、存放位置分类 1.当前项目根目录下的config目录下 2.当前项目的根目录下 3.resources目录下的config目录下 4.resources目录下 按照这上面的顺序,4个配置文件的优先级依次降低。 我们在项目里面4个位置分别设置了各种的application.properties文件。每个文件…

MySQL查看和修改最大连接数

标题:MySQL查看和修改最大连接数 MySQL 是一种广泛使用的开源关系型数据库管理系统,被许多应用程序用作其后端存储解决方案。在高并发的环境下,MySQL 的最大连接数变得尤为重要。本文将介绍如何查看当前的最大连接数,并详细说明每…