spring mysql 事务回滚失败_技术贴 | Spring事务不回滚问题排查

原标题:技术贴 | Spring事务不回滚问题排查

99585dbe5bed4c975c9af2d3e026fdaa.png

本技术贴是我司技术小哥在开发新项目中遇到的问题时的分析及思考,学霸的人生学无止境。

01

问题描述

在新项目的开发中遇到一个奇葩的问题:方法添加了事务后数据库不回滚,而且不是每一个方法都不回滚,是有的方法回滚,有的不回滚。

02

问题背景

新项目使用SpringBoot2.0+Mybatis框架,启用事务的方式是在类的方法上使用@Transactional注解的方式来启用事务的

(旧项目直接在类上面加@Transactional,该类下所有方法都支持事务,考虑到一些查询方法是不需要事务的,这样会影响性能,所以改为在方法上添加@Transactional注解,所以旧项目事务没有出现问题)。

03

排查问题

经过对比发现:

回滚的方法都是由controller直接调用有@Transactional注解的,而不回滚的方法都是由controller调用了方法A(该方法没有声明事务),再由方法A调用方法B(该方法声明了事务)

例如:测试类TestController

cd2421cc63be2586c85fd40a7e2a4bf2.png

TestOneServiceImpl

dbe36618a7cc8820a09341f4fcea3102.png

TestController类中的test()方法调用了

TestOneServiceImpl中的testFunctionOne() 方法

testFunctionOne()方法调用了 testFunctionTwo()方法(启用了事务) 。

如果事务起作用,则user对象中userName字段不会更改

首先查询userName值

d0239b020a2b7dd54cc621440a5ba160.png

调用 test()方法 查询数据库

94ac3551d9aa2ddec74fc6ccbbcf0980.png

发现userName值已被更改 ,testFunctionTwo()方法中的事务没起作用

在test()方法中直接调用testFunctionTwo()方法

94bd62d10947b31234bbc57b0ffca63b.png

调用前userName值

5faa7f2c7a3d9ded118bec3f3ce3d40e.png

调用后userName值

c1ac8d00bd9b3313a4b34a5f3c52aa56.png

发现userName值未被更改 ,testFunctionTwo()方法中的事务起作用了,数据库回滚,复现了项目中的问题。

经过查询spring官网 发现原文

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behaviour so you should not rely on this feature in your initialization code, i.e. @PostConstruct.

大体意思是 默认的代理模式下,只有被代理拦截的外部方法。这意味着,自调用即类内部方法调用本类内部的其他方法并不会引起事务行为(即使该方法被@Transactional注解标记)。

由上可见,新项目中事务不回滚的原因已被找到。

04

解决方案

无脑方式:

将需要事务的方法提到另一个类中

官方解决方案:

使用AspectJ[JL1] 代理模式替代默认代理(暂未实现)

通过初始化方法在目标对象中注入代理对象

0caa9366fa88b816ca584a170fe8516e.png

调用前userName值

c53d9e52110547cdff7bb90bd04b73fc.png

调用后userName值

a9e0b52552a7712afe06a3eca6b5b410.png

小结

经过这次事件 认真学习了一下spring事务的注意事项总结如下:

默认代理模式下 只有public修饰的方法事务才起作用, private protected 包内可见方法即使用@Transactional声明了事务,不会出错 也不会起作用(可以使用AspectJ代理来解决)

任何 RuntimeException 抛出时触发回滚, 检查异常抛出时不会回滚。如果想实现抛出检查异常回滚需在@Transactional中添加属性rollbackFor 指定需要回滚的异常类 norollbackFor 自定义不回滚异常

默认的代理模式下,只有被代理拦截的外部方法才事务才回起作用。自调用即类内部方法调用本类内部的其他方法并不会引起事务行为(即使该方法被@Transactional注解标记)。 如果想实现自调用 需更换代理模式 使用AspectJ代理来解决

异常如果被catch住了并且没有抛出 事务是不会起作用的

感谢李斌对此次故障排查做出的贡献

参考文献:Spring官方文档

https://docs.spring.io/spring/docs/4.3.13.RELEASE/spring-framework-reference/htmlsingle/#transaction-declarative-annotations返回搜狐,查看更多

责任编辑:

【事务】- mysql事务和neo4j事务冲突导致mysql事务不生效 springboot-mysql事务回滚不生效问题 阅读详情

相关推荐

Spring事务回滚机制深度解析:从@Transactional注解到数据库原子操作

在数据库操作中,事务是确保数据一致性的核心机制,它遵循ACID原则,保证一系列操作要么全部成功,要么全部失败。其原理基于数据库引擎的原子性实现,通过事务日志和锁机制维护数据状态。这一技术价值在于防止数据不一致,广泛应用于支付系统、订单处理等关键业务场景。Spring框架通过AOP和代理模式,将事务管理抽象为声明式编程,其中事务回滚是处理异常状态的关键环节。本文结合Spring AOP和数据库连接管理,深入探讨了@Transactional注解背后的回滚决策与执行链路,帮助开发者理解并避免常见的事务失效问题。

weixin_30414305的博客 379

SpringBoot事务不回滚,不生效

常见坑点1:遇到检测异常时,事务默认不回滚。 SQLException 原因分析:因为Spring的默认的事务规则是遇到运行异常(RuntimeException及其子类)和程序错误(Error)才会进行事务回滚,显然SQLException并不属于这个范围。如果想针对检测异常进行事务回滚,可以在@Transactional 注解里使用 rollbackFor 属性明确指定异常。例如下面这样,就可以正常回滚 @Transactional(rollbackFor = Exception.class) 常见

qq_38693803的博客 1961

手眼标定(EyeToHand)推导

Base为基坐标系(B),工具末端坐标系(T),标定板为Mark坐标系(M),相机坐标系(C)对于每两个姿态都存在上式,组成一个AX=XB的矩阵方程,X为。此时转换成AX=0的问题,单纯用SVD求奇异解便可得到。相机坐标系到Base基坐标系下的转换关系。已知标定板与机械臂末端的相对位置固定不变,,即。带入(2)式求,至此求解出需要的手眼矩阵。在眼在手外的时候,其实是要求解。

stevenreally6的博客 1143

springboot连接mysql8,transactional结果不能回滚

spring boot;mysql8;Transactional;事务回滚;java

andyhas的博客 703

如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi

本文介绍了在Ubuntu 24.04上安装和使用GDebi的方法。GDebi是DPKG的轻量级替代品,能够自动解析并安装.deb包的依赖项。文章详细说明了系统更新、安装GDebi的步骤,并演示了通过GUI和CLI两种方式安装.deb包的操作流程。此外,还提供了验证安装和卸载包的方法。GDebi虽然非必需,但为用户提供了处理依赖项的另一种选择,适合需要安装本地Debian包的用户。

山岚的运维笔记 1985

实战指南:从零开始用YOLOv8训练VisDrone无人机检测模型

本文提供了一份详细的实战指南,手把手教你从零开始使用YOLOv8训练一个无人机检测模型。内容涵盖VisDrone数据集下载与格式转换、YAML配置文件编写、模型训练与评估,以及最终的推理部署,旨在帮助开发者快速掌握无人机视角下的目标检测技术。

salt的博客 682

springboot+mybatis事务无法回滚(解决)

在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,框 架会自动默认分别注入DataSourceTransactionManager或JpaTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用。 找到pom文件中有没有spr...

孟林洁的博客 8200

C++实战指南:使用CodeBlocks构建跨平台wxWidgets窗口应用

本文是一份面向C++初学者的实战指南,详细介绍了如何使用CodeBlocks IDE和wxWidgets框架快速构建跨平台的桌面窗口应用。内容涵盖从环境搭建、项目配置到界面设计、事件处理的全流程,重点讲解了如何利用CodeBlocks的开箱即用支持和wxSmith可视化设计器,高效开发具有按钮、菜单、列表等控件的交互式窗口界面程序,帮助读者轻松入门GUI开发。

weixin_29012677的博客 154

springboot使用mybatis事务失效(多数据源原因)

1、springboot整合mybatis后,直接使用@EnableTransactionManagement 注解可以开启事务,然后代码中使用 @Transaction注解即可。 2、作者是使用了mybatis + neo4j俩个数据库,就导致了有俩个数据源,mysql发生异常后事务没有发生回滚,跟踪spring的事务代码后发现默认的事务管理器使用了neo4j的事务管理器,...

一个人的世界 9537

实战指南:如何用Kamailio+FreeSWITCH搭建高并发企业通信系统(附配置模板)

本文提供了一份实战指南,详细介绍了如何利用Kamailio与FreeSWITCH构建高并发企业通信系统。通过将Kamailio作为高性能SIP信令平面处理路由与负载均衡,FreeSWITCH作为媒体与应用平面负责通话与业务逻辑,实现信令与媒体分离的电信级架构。文章深入解析了架构设计、核心配置、集群部署与性能优化,并附有配置模板,旨在帮助企业构建可水平扩展、高可用的通信解决方案。

dell8的博客 364

c++实现异步线程池并详细分析线程池析构流程

多线程编程是提高程序性能和响应能力的关键技术之一,异步线程池作为多线程编程的一种有效实现方式,能够管理和复用线程资源,避免频繁创建和销毁线程带来的开销。在本文中,我们将深入探讨如何实现一个异步线程池。

2301_76564925的博客 1599

终极办法:解决spring mvc+mysql+mybatis事务不提交不回滚的问题

网上逛了一大圈,终于解决了,我是网文搬运工,把我解决的过程放出来供大家参考。 首先:要确定你的数据库是否是支持事务,再往下看 一:事务使用。 先来一个普级稿,几种事务的配置方法: 1. myBatis单独使用时,使用SqlSession来处理事务: Java代码   public class MyBatisTxTest {        privat

aattxx的博客 1万+

BoT-SORT实战:手把手教你实现BoT-SORT训练和测试

文章目录摘要1、数据准备2、配置BoT-SORT环境2.1、获取代码2.2、创建虚拟环境2.3、安装必要的包2.3.1、安装pytorch2.3.2、安装cython2.3.3、安装Cython-bbox2.3.4、安装faiss2.3.5、安装其他的包3、训练3.1、生成REID数据集3.2、预训练模型3.2.1、ByteTrack预训练模型3.2.2、REID预训练模型3.3、开始训练4、如何更改FASTREID的BackBone?5、测试5.1、测试视频5.2、测试摄像头5.3、多类别测试 摘要 Bo

m0_47867638的博客 2298

jpa transaction 回滚_spring data jpa使用@Transactional注解开启事务后失败不回滚

如题,在数据库批量操作方法上使用@Transactional注解,其中一条数据抛出异常了,却死活不回滚。批量操作方法是公有的,spring也是默认支持事务的,排除代码层面问题,那么就看看数据库是否支持事务吧:mysql>show engines;+--------------------+---------+------------------------------------------...

weixin_39728213的博客 846

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Spring事务无法回滚异常处理记录与小结

Spring事务的概述 事务(Transaction):在数据库中,可以保持一系列的数据操作要么全部执行成功,要么全部执行失败的机制!在基于Spring JDBC的编程中,只需要为业务方法加上@Transactional注解,就可以使得该业务方法中的多条数据操作是有事务的保障的,这多条数据操作要么全部成功,要么全部失败,不会出现成功一半且失败一半的问题! 主要原理是在提交2次sql事务时会现在内存中操作,然后没有异常了再提交到数据库,如果在内存中报错了那么就不提交到数据库以实现回滚. 摘自成大佬笔记-.-

weixin_45577016的博客 2137

Statistics and Machine Learning Toolbox

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

为什么你的@Transactional事务没有回滚?从内部调用失效到掌握事务之道

我不是加了@Transactional注解吗,怎么数据又没回滚。要是有一个仁厚、正直、诚信、谦和、忠恕、清廉、高洁、温润、儒雅、端方、恭谨、庄重、内敛、沉稳、睿智、豁达、淡泊、温良、恭俭、谦让、坦荡、中和、包容、自律、慎独的Java高手帮我排查就好了

2402_89042144的博客 1357

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring Boot事务管理实战:自动回滚与手动控制

事务管理是保证数据一致性的核心技术,基于ACID特性实现数据库操作的原子性和一致性。Spring Boot通过@Transactional注解提供声明式事务支持,其底层通过AOP代理实现事务的自动开启、提交与回滚。在分布式系统和复杂业务场景中,开发者需要掌握事务传播行为、隔离级别等核心概念,并能够根据业务需求选择自动回滚或手动控制方案。本文重点解析Spring事务的自动回滚机制与TransactionTemplate编程式事务管理,涵盖事务失效场景排查、性能优化建议等实战经验,帮助开发者正确处理库存扣减、订

weixin_33910385的博客 456

Spring Boot事务实战:从自动回滚到部分回滚,彻底解决数据不一致

在分布式系统和微服务架构中,数据一致性是企业级应用的核心命脉。Spring框架通过声明式事务管理,利用AOP代理机制为开发者提供了简洁的@Transactional注解,然而许多人在实际项目中仍会遭遇事务不回滚、异常被吞、自调用失效等棘手问题。理解事务回滚的底层原理与传播行为,是保障订单、库存等关键数据准确性的基础。围绕这一痛点,内容从事务的核心机制讲起,梳理自动回滚、手动回滚及部分回滚的适用场景与实现方案,结合电商、支付等典型业务案例,深入剖析REQUIRES_NEW、Savepoint等实战技巧,并探讨

weixin_31220401的博客 268

Spring 事务不回滚?5 个容易忽略的非典型场景

本文总结了Java中@Transactional注解事务失效的5个隐蔽场景及解决方案:1.异常被try-catch捕获未抛出(需手动标记回滚或重新抛出异常);2.传播级别配置错误(写操作应使用默认REQUIRED);3.跨线程调用导致事务上下文丢失(需异步方法独立管理事务);4.使用MyISAM等不支持事务的存储引擎(需改用InnoDB);5.在只读事务中执行写操作(应读写分离)。文章提供了详细代码示例和修复方案,并附上事务失效排查清单,强调事务失效问题多源于细节疏忽而非技术难度。

Vinteenn的博客 503

数据库事务回滚与Spring事务管理实战解析

事务回滚是数据库ACID特性的核心机制,通过undo log实现操作撤销,确保数据一致性。在分布式系统中,2PC、TCC和Saga等模式解决了跨服务事务难题。Spring框架通过AOP代理实现声明式事务管理,但需注意自调用失效等问题。合理设置传播行为和隔离级别能有效平衡性能与一致性,如REQUIRES_NEW适合独立操作,READ COMMITTED兼顾并发与数据准确性。实战中,乐观锁、异步处理和事务拆分是提升性能的关键技巧。

weixin_30644369的博客 526

电商3PC事务失败:HikariCP连接超时与事务配置问题

💡 亲爱的技术伙伴们:你是否正在为这些问题焦虑——✅ 简历投出去杳无音信,明明技术不差却总卡在面试?✅ 每次终面都紧张不已,不知道面试官到底想要什么答案?✅ 技术知识点零零散散,遇到系统设计题就头脑一片空白?🎯这不是普通的面试题汇总,而是凝聚多年面试官经验的。我不仅告诉你答案,更帮你建立面试官的思维模式。🔗🎯 精准人群定位🔥 《》(完整技术体系)🚀⚡🌊🛠️🔒🔄👥🏗️🚀 立即行动,改变从现在开始!🔗不要再让面试成为你职业发展的绊脚石!用时间系统准备,轻松应对各种技术面试场景。💪。

AIHacksCash的博客 863

Spring @Transactional 事务失效的 5 种场景排查与修复方案

本文深入分析了Spring @Transactional注解事务失效的5种典型场景,包括非public方法调用、类内部方法调用、异常处理不当、数据库引擎不支持事务以及传播行为配置错误。针对每种场景提供了详细的解决方案和最佳实践,帮助开发者有效排查和修复事务管理问题,确保数据一致性。

tyygming的专栏 456

Neo4j 事务管理器冲突导致 MySQL 事务失效 — 排查与修复技术文档

项目同时引入 Spring Data Neo4j 与 MySQL 时,Neo4j 自动配置抢先注册了 `Neo4jTransactionManager`,导致 JDBC 事务管理器因 `@ConditionalOnMissingBean` 条件不满足而从未创建。此后所有未显式指定事务管理器的 `@Transactional` 实际开启的都是 Neo4j 事务,对 MySQL 连接毫无约束(`autoCommit=true`),异常后无法回滚,产生脏数据。

生如夏花的博客 424
上一篇: python sklearn逻辑回归 sgd和lr_sklearn逻辑回归
下一篇: dg修改归档目录 oracle_12C RAC+DG+Broker 修改归档日志路径的方法。
美美bv
博客等级 码龄8年 31粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值