当前位置: 首页 > news >正文

@Transaction注解失效的几种场景(附有示例代码)

目录

0 说明

一、抛出检查异常导致事务不能正确回滚

二、业务方法内自己 try-catch 异常导致事务不能正确回滚

三、AOP 切面顺序导致导致事务不能正确回滚

四、非 public 方法导致的事务失效

五、父子容器导致的事务失效

六、调用本类方法导致传播行为失效

七、@Transactional注解没有保证原子行为

八、@Transactional 方法导致的 synchronized 失效


0 说明

当使用 @Transactional 注解时,可能会出现失效的情况。这种失效可能由于各种因素造成,比如异常处理、AOP切面的顺序、方法的可见性等。失效可能会导致事务无法正确地回滚或提交,从而影响数据的一致性和完整性。以下是八种常见的@Transaction注解失效的场景。

一、抛出检查异常导致事务不能正确回滚

当一个受 @Transactional 注解管理的方法中抛出了检查异常(即继承自 Exception,而非 RuntimeException),Spring 会默认将其视为受检查异常,并不会触发事务的回滚。因此,若想确保事务正确回滚,应当将异常转换为运行时异常。

@Service
public class ExampleService {@Autowiredprivate ExampleRepository repository;@Transactionalpublic void updateData() {try {repository.update(); // 抛出检查异常} catch (SQLException ex) {throw new RuntimeException(ex); // 转换为运行时异常}}
}

二、业务方法内自己 try-catch 异常导致事务不能正确回滚

如果在事务方法内部捕获了异常并进行了处理,而没有将其重新抛出或者抛出非 RuntimeException,则事务不会被回滚。

@Service
public class ExampleService {@Autowiredprivate ExampleRepository repository;@Transactionalpublic void processData() {try {// 业务逻辑} catch (Exception ex) {// 异常处理,但未重新抛出}}
}

三、AOP 切面顺序导致导致事务不能正确回滚

如果在事务方法中使用了 AOP 切面,并且切面的顺序不正确,可能会导致事务失效。通常情况下,应确保事务切面的顺序在其他切面之前。

@Aspect
@Component
public class ExampleAspect {@Around("execution(* com.example.service.ExampleService.*(..))")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {// 前置逻辑Object result = joinPoint.proceed(); // 调用目标方法// 后置逻辑return result;}
}

四、非 public 方法导致的事务失效

Spring 的事务代理是通过代理对象来实现的,因此 @Transactional 注解只对公有方法有效。非公有方法如果被其他方法内部调用,则事务不会被切面代理管理,导致失效。

@Service
public class ExampleService {@Transactionalpublic void publicMethod() {// 业务逻辑}@Transactionalprivate void privateMethod() {// 业务逻辑}public void callerMethod() {privateMethod(); // 被调用的非公有方法内的事务失效}
}

五、父子容器导致的事务失效

在 Spring 中,如果父子容器的配置不正确,可能会导致事务失效。一种常见情况是父容器和子容器分别管理了事务,但子容器中的事务不会受父容器的影响,导致事务操作失效。

@Configuration
@EnableTransactionManagement
public class ParentConfig {@Beanpublic DataSource dataSource() {// 配置数据源}@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}
}@Configuration
@EnableTransactionManagement
public class ChildConfig {@Beanpublic DataSource dataSource() {// 配置不同的数据源}@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}
}

六、调用本类方法导致传播行为失效

如果在同一个类中调用带有 @Transactional 注解的方法,Spring 的事务传播行为可能会失效。因为 Spring 通过 AOP 代理来管理事务,同一个类内的方法调用并不会触发代理,事务传播行为不会被应用。

@Service
public class ExampleService {@Transactionalpublic void methodA() {methodB(); // 调用本类方法}@Transactional(propagation = Propagation.REQUIRES_NEW)public void methodB() {// 事务传播行为 REQUIRES_NEW 失效}
}

七、@Transactional注解没有保证原子行为

虽然 @Transactional 注解可以确保一组操作要么全部成功,要么全部失败,但它并不能保证原子性操作。如果在一个事务方法中出现多个数据库操作,并且某些操作成功,而其他操作失败,那么只有失败的那部分会回滚,而成功的部分会保留,这可能导致数据不一致。

@Service
public class ExampleService {@Autowiredprivate ExampleRepository repository;@Transactionalpublic void updateData() {repository.updateData1(); // 更新操作1repository.updateData2(); // 更新操作2// 操作2失败,但操作1已提交,数据不一致}
}

八、@Transactional 方法导致的 synchronized 失效

如果一个方法同时使用了 @Transactional 和 synchronized 注解,那么 synchronized 的锁将被事务代理所绕过,导致锁的失效,多个线程可能同时访问该方法,破坏了同步性。

@Service
public class ExampleService {@Transactionalpublic synchronized void process() {// 事务方法}
}

在上述代码中,尽管 process 方法被声明为 synchronized,但由于被 @Transactional 注解修饰,Spring 的事务代理会绕过 synchronized 锁,导致同步失效。

相关文章:

  • 蓝桥杯----凑算式
  • C遗漏知识(个人向)
  • git将项目的某次签入遴选(Cherry-Pick)另一个项目
  • 聚观早报 | iOS 17.4正式版将上线;魅族21 Pro或下月发布
  • 12. onnx转为rknn测试时有很多重叠框的修改(python)
  • C语言中的函数指针、指针函数与函数回调
  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之MenuItem组件
  • ref和reactive, toRefs的使用
  • 【RL】Basic Concepts in Reinforcement Learning
  • Day01-变量和数据类型课后练习-参考答案
  • 《C程序设计》上机实验报告(六)之函数及其应用
  • BC107 矩阵转置
  • 踩坑实录(First Day)
  • SpringBoot之整合PageHelper分页插件
  • 代码随想录算法训练营DAY14 | 二叉树 (1)
  • 2017 年终总结 —— 在路上
  • Apache的80端口被占用以及访问时报错403
  • codis proxy处理流程
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • JS 面试题总结
  • js中的正则表达式入门
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Spring-boot 启动时碰到的错误
  • vue中实现单选
  • Web Storage相关
  • 算法系列——算法入门之递归分而治之思想的实现
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # Panda3d 碰撞检测系统介绍
  • (1)(1.11) SiK Radio v2(一)
  • (2021|NIPS,扩散,无条件分数估计,条件分数估计)无分类器引导扩散
  • (k8s中)docker netty OOM问题记录
  • (编译到47%失败)to be deleted
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (十八)三元表达式和列表解析
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)大型网站的系统架构
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • **PHP分步表单提交思路(分页表单提交)
  • .aanva
  • .htaccess 强制https 单独排除某个目录
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET 5种线程安全集合
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET 常见的偏门问题
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .Net程序帮助文档制作
  • .Net的C#语言取月份数值对应的MonthName值
  • .net下的富文本编辑器FCKeditor的配置方法
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • /bin、/sbin、/usr/bin、/usr/sbin
  • /etc/sudoers (root权限管理)
  • @RestControllerAdvice异常统一处理类失效原因
  • [BT]BUUCTF刷题第4天(3.22)
  • [C++随笔录] 红黑树
  • [CareerCup] 12.3 Test Move Method in a Chess Game 测试象棋游戏中的移动方法