【问题总结】由于Spring事务使用不当引起的数据库死锁

Spring 动态数据源事务处理 在一般的 Spring 应用中,如果底层数据库访问采用的是 MyBatis,那么在大多数情况下,只使用一个单独的数据源,Spring 的事务管理在大多数情况下都是有效的。然而,在一些复杂的业务场景下,如需要在某一时刻访问不同的数据库,由于 Spring 对于事务管理实现的方式,可能不能达到预期的效果。本文将简要介绍 Spring 中事务的实现方式,并对以 MyBatis 为底层数据库访问的系统为例,提供多数据源事务处理的解决方案。 阅读详情

现象

这次版本发完生产不久,主管就在群里通知了数据库有性能问题,产生了死锁。
在这里插入图片描述
在这里插入图片描述
这条SQL一直没有执行结束,导致系统其它服务都出现性能问题。

背景

这是一条更新人员索引日志表的SQL,这张表的作用就是用来标记哪些人员的数据发生变化。

涉及这条SQL的模块有后台任务和操作人员数据的功能。

后台任务从这张表获取需要更新的人员,将数据同步到solr。

操作人员数据的功能需要在这张表中标记该人员为待更新。

分析

产生问题的可能有这两个模块:一个是后台任务,一个操作人员数据的功能。

这两个模块如果同时更新同一个人员,并且一方的执行时间比较长,事务未提交,而另一方在此时提交事务,那就会产生问题。

后台任务

逻辑不复杂,而且包含更新日志表的操作的事务逻辑简单,不存在耗时问题。

操作人员数据的功能

拿审核人员举例,审核人员包括一系列的流程:校验参数、更新信息、更新日志表、调用接口、发送邮件。

这一系列流程都是在同个事务中进行的,调用接口和发送邮件是比较耗时的操作。原先是没啥问题的,但是后来加的更新日志表,这个方法操作的表就是跟后台任务更新人员索引操作的表是同一张表。

产生问题的过程

1、该人员在日志表中的状态为未更新(其他操作导致状态为未更新)
2、正在执行审核该人员的功能,由于耗时较长,事务还未提交
3、后台任务遍历到了该人员,准备更新状态时,就出现了问题

解决方法

对Spring事务传播行为有所了解的朋友,应该就知道解决方法了。(Spring默认的事务传播行为是REQUIRED)

既然由于审核操作耗时太久,更新日志表的事务未能及时提交,那就想方法把更新日志表的事务先提交,别占用太多时间。

我这里使用的方法是在更新日志表的方法上加上@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW),这里的意思就是为该方法开启一个新的事务,当该方法结束时就提交事务。这样一来这个简单的方法就可以马上提交对日志表的操作,而不会因为审核操作太耗时而占用事务太多时间。

关于Spring事务的使用,这里需要避免一个坑:《Spring中AOP调用失效的处理方式》

死锁产生的条件及其预防 破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,… 阅读详情

相关推荐

[附源码]计算机毕业设计-Steam游戏平台系统论文Springboot程序

项目运行环境配置:(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可4.

JSP、ssm毕设程序源码 1494

spring事务问题分析

spring事务问题分析,一、spring事务的原理 二、事务容易引发的问题 三、为什么事务执行时间不能太长 四、复杂业务逻辑如何规避事务问题

mufengluoyu的博客 764

Python小白也能玩转迅投QMT量化交易?手把手教你从安装到第一个策略

本文为零基础Python用户提供了上手迅投QMT量化交易平台的完整指南。从Python 3.6环境配置、QMT客户端获取安装,到核心概念讲解,并手把手教你编写并回测一个经典的双均线交易策略,帮助初学者快速迈出量化交易的第一步。

weixin_29103191的博客 763

spring事务的传播机制与事务挂起

事务的传播机制:(不是JDBC事务管理)用来解决业务层的事务之间调用的问题。 PROPAGATION_REQUIRED :支持(使用)当前事务,如果不存在事务就创建一个新事务 *方法A中调用方法B: 如果方法A有事务,B方法就使用方法A的事务。如果A没有事务,就创建一个新事务。(A,B在同一个事务中) PROPAGATION_SUPPORTS :支持(使用)当前事务,如果不存在事务就不使用事务 ...

wr_java的博客 797

机器视觉/将HIK海康面阵相机连接Halcon软件

本文简述了如何将海康面阵相机连接到Halcon软件中进行实时取图的过程。

Dahe.qu 4866

Ubuntu20.04系统笔记本网卡AX211无法找到wifi问题

之前电脑的系统是18.04基本上安装好了系统,可以直接连上wifi,在买了拯救者y9000p2022版本之后,因为网卡太新,安装ubuntu18.04或者20.04之后会没有wifi连接,非常不方便。于是上网找了各种帖子去解决这个问题。具体实现有所不同。 主要参考了这个帖子来解决的:http://t.csdn.cn/7807R 首先: sudo apt install flex bison 然后: git clone https://github.com/intel/backpor.

weixin_42825962的博客 1万+

springboot项目在多表联合查询的时候报空值异常

Transaction synchronization closing SqlSession [org. apache.ibatis, session,defaults, DefaultSglSession01186abcel 2022-03-0419:06:29.7791R80816704---[nio-8080-exec-7]a.a.c.e ol.l.ly:dishetche servlet: Servlet, service0 for serylet dispatch### Error queryin

weixin_59141958的博客 2387

自学 ABAP 和自学 SAP 的差别

有朋友在我的 ABAP 学习教程里留言: > 自学SAP是不是都要搭建虚拟服务器,然后自己去官网下载新版本SAP就可以吗 对于初学者,我们要搞清楚 ABAP 和 SAP 的区别。 ABAP 是一门编程语言,SAP 首先是德国软件公司的名称,也代表这家公司开发的一系列软件。SAP 公司开发的软件,我们有时也称产品,其功能能满足客户一个或者多个领域的业务需求。这些不同领域,我们也称为不同的业务模块,比如 ERP,CRM,SRM,HR 等等。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 6862

MySQL中Spring管理的事务开启后不提交引起的事故

了解到一个事故,在MySQL数据库中,使用Spring管理的事务在开启以后没有在操作结束时提交或回滚,使得原有线程在后续执行数据库操作时可能继续使用原有事务,且不会提交,导致对数据库的修改在Java应用层认为是成功,但在数据库层最终是没有生效的,产生了比较严重的后果

adrninistrat0r的博客 9982

【AUTOSAR-CanNM】-3.1-如何让ECU发出的首帧是NM帧(Tx Nm报文先于Tx App应用报文发出)

如何让ECU发出的首帧是NM帧(Tx Nm报文先于Tx App应用报文发出)

「汽车电子助手」的博客 4723

如何用matlab扫频法测考虑频率耦合的并网逆变器的序阻抗,如何实现?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1192

长事务@Transactional(死锁、连接不足)

在Spring中进行事务管理非常简单,只需要在方法上加上注解@Transactional,Spring就可以自动帮我们进行事务的开启、提交、回滚操作。甚至很多人心里已经将Spring事务@Transactional划上了等号,只要有数据库相关操作就直接给方法加上@Transactional注解。 /** * 代码片段1 */ @Transactional(rollbackFor = Exception.class) public void save(RequestBillDTO r...

woshimyc的专栏 1万+

CannotAcquireLockException——Spring事务嵌套死锁

bug如下: java.sql.SQLException: Lock wait timeout exceeded | org.springframework.dao.CannotAcquireLockException 检查了代码,sql都没有问题;引起bug的原因是在一个service中调用了另一个service,两个都有自己的事务,所以嵌套形成死锁。(但是很奇怪,之前的代码一直运行没有问...

Ashley_Peng的博客 2519

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Spring事务死锁

今天同时导入两个比较耗时的批量操作,系统抛出了异常如下  org.springframework.dao.DeadlockLoserDataAccessException:  ### Error updating database.  Cause: java.sql.SQLException: ORA-00060: 等待资源时检测到死锁   ### The error may invol...

yaochao211的博客 2232

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数据库事务隔离级别与Spring传播行为深度解析

摘要:本文深入剖析数据库事务隔离级别与Spring传播行为的技术原理与实战应用。通过电商支付、批量处理等真实案例,揭示事务管理的核心难点:脏读、不可重复读、幻读等并发问题,以及死锁、性能下降等常见陷阱。文章对比了四种隔离级别(READ UNCOMMITTED到SERIALIZABLE)的实现机制与性能差异,详解Spring七种传播行为的工作流程,提供源码级分析。针对企业级场景,给出支付系统、批量处理等典型场景的优化方案,包括事务拆分、异步处理等技巧,并配套监控配置与故障排查方法。最后总结出"事务军

七夜zippoe的博客 2635

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

一文说清楚Spring事务中的大事务问题以及什么情况下@Transation注解会失效

如果我们的Transational注解里面的rollbackFor我们没有指定成所有异常Exception,那么我们就默认只会遇到RuntimeException的时候我们才回滚

LUCIAZZZ的博客 1373

MySQL InnoDB(Spring)并发事务导致的死锁及解决方案

用MySQL客户端模拟并发事务操作数据时,如下表按照时间的先后顺序执行命令,会导致死锁。 数据库数据如下 select * from a ; +----+ | id | +----+ | 3 | +----+ | 8 | +----+ | 11 | +----+ 时间 会话A 会话B 1 begin; 2 delete from a where id = 4; ...

p7+的博客 1万+

在事务和重试机制下,死锁导致的数据丢失。

在使用retry处理死锁时,需要注意的地方。

duan614的博客 1538

高并发下数据库插入操作死锁问题

比如说本篇博客中的A表与B表可以校验两者的数据一致性,因为高并发会时时刷新数据,因此即使是死锁造成的短暂的数据不一致,在下一次刷新时,也会刷新为最新的数据。此场景在多线程批量同时对两张表进入插入操作,一张A表,一张B表,A表是原始数据表,B表是处理数据表,插入B表时,每批次插入数据量为50,产生死锁导致数据不一致问题。在一个事务中的 INSERT 按照主键或唯一键的顺序增序插入,即 session1 可以先插入 a=33 的记录,再插入 a=35 的记录,可一定程度避免受到 GAP 锁的影响。

一瓢西湖水的博客 3311

Spring boot项目 MySQL数据库死锁----父线程开启事务导致数据库死锁

在一次操作中出现数据库死锁,异常栈如下可以看到 出现了CannotAcquireLockException,无法获取到锁,通过搜索引擎查询到,该异常通常是死锁引起的。

qq_41539807的博客 1464

【高并发基础】Spring 事务传播级别及造成死锁的隐患分析

本项目聚焦高并发的基础知识,至底向上得研究:github 仓库 (分支 master / isolation / propagation / multithreading) 理念:事务传播行为官网描述 用于区分声明式事务catch到异常由框架回滚,本文的“回滚”用到编程式事务的API 支持主动回滚。编程式事务官网描述 讨论的模型是 调用方(外层) -> 被调用方(内层)默认传播行为, 确保当前方法一定处于事务保护中用于减少事务的粒度,如果不是关键的业务逻辑或是运行出错的逻辑,可以用 声明与调用方事务隔离。

chenghan_yang的博客 2439

mysql死锁产生原因以及如何删除锁定的事务线程

问题现象:   接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现Lock wait timeout exceeded; try restarting transaction的错误 问题场景:   1、在同一事务内先后对同一条数据进行插入和更新操作;   2、多台服务器操作同一数据库;   3、瞬时出现高并发现象; 问题原因:   1、在高并发的情况下,Spring事物造成数...

Lylbp 1万+

Mysql死锁与spring事务

MySQL死锁从产品之初就偶有发生,算是萦绕在心中的噩梦之一。由于死锁大都伴随着锁等待,所以一般都会拉低服务QPS,在死锁发生时肯定会出现各种意料不到的问题。前期一直采用“指标不治本”的办法,对特别容易产生死锁的方法增加retry。但当retry和事务嵌套在一起时也会出现不可预知的错误。 对于数据库死锁这个万恶之源,真可谓深恶痛绝,所以这次在解决retry和事务嵌套问题时,将这个元凶也一并解决。 一些关于事务的概念 为了更好的说明问题,我们先来解释一下基本概念 隔离级别 Tran...

dw147258dw的专栏 1023

多线程事务死锁问题分析总结(实战应用)

Spring 事务 首先来看事务的四个特性: 原子性 事务的执行将事务内所做的操作看做一个整体, 要么全部执行, 要么全部不执行. 隔离性 (可能导致死锁) 简单来说, 两个事务在同时进行更新时,一个事务在更新, 另一个事务需要操作时,不可能看到这条记录之前的值, 需要等到之前的事务要么执行(事务提交),要么不执行(事务回滚). 才可以继续对该记录进行操作. 这也是事务的其中一个隔离级别...

2151

Spring事务

本文讲解的是Spring事务,Spring事务的实现方式,隔离级别事务的传播机制,以及失效情况。

tq02的博客 1403
上一篇: 《Java并发编程实战》学习笔记(2)
下一篇: 《Java并发编程实战》学习笔记(3)
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值