Spring事务 - Spring事务失效的场景

news/2024/10/10 18:20:55

Spring事务失效的场景

   概要

   用一个事务注解@Transactional来控制事务,底层实现是基于切面编程AOP实现的,而Spring中实现AOP机制采用的是动态代理,具体分为JDK动态代理和CGLIB动态代理两种模式。

1. Spring的bean的初始化过程中,发现方法有Transactional注解,就需要对相应的Bean进行代理,生成代理对象。
2. 然后在方法调用的时候,会执行切面的逻辑,而这里切面的逻辑中就包含了开启事务、提交事务或者回滚事务等逻辑。

   注意:Spring 本身不实现事务,底层还是依赖于数据库的事务。没有数据库事务的支持,Spring事务是不会生效的。

   有时候,我们明明在类或者方法上添加了@Transactional注解,却发现方法并没有按事务处理。其实,以下场景会导致事务失效。

   一、Spring框架、配置问题

   1. 没有被Spring管理

1 // @Service
2 public class OrderServiceImpl implements OrderService {
3     @Transactional
4     public void updateOrder(Order order) {
5         // update order
6     }
7 }

   Spring声明式事务的实现完全依赖于Spring的AOP代理机制,未被Spring管理的类中的方法不受Spring的AOP代理管理,因此,声明式事务失效。

   这里将@Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。

   事务不生效原因

   @Service注解注释之后, Spring事务( @Transactional)没有生效,是因为 Spring事务是由 AOP机制实现的,也就是说从 Spring IOC容器获取 bean时, Spring会为目标类创建代理,来支持事务的。但是 @Service被注释后,这个service类都不是 spring管理的, 那怎么创建代理类来支持事务呢。

   解决方案:

   需要保证每个事务注解的每个Bean被Spring管理。

   2. 没有在Spring配置文件中配置事务管理器或启用事务管理器。

 1 @Configuration
 2 public class AppConfig {
 3     // 没有配置事务管理器
 4 }
 5 
 6 @Service
 7 public class MyService {
 8     @Transactional
 9     public void doSomething() {
10         // ...
11     }
12 }

   事务不生效原因:

   如果没有配置事务管理器或未启用事务管理,使用 @Transactional 注解时,Spring 将不会对方法进行事务处理,导致事务失效。事务管理器负责创建、提交和回滚事务,是实现事务控制的核心组件。

   解决方案:

   在 AppConfig中配置一个事务管器并且启用事务管理器

 1 @Configuration
 2 @EnableTransactionManagement
 3 public class AppConfig {
 4     @Bean
 5     public PlatformTransactionManager transactionManager() {
 6         return new DataSourceTransactionManager(dataSource());
 7     }
 8 }
 9 
10 @Service
11 public class MyService {
12     @Transactional
13     public void doSomething() {
14         // ...
15     }
16 }

   说明:如果是Spring Boot项目,它默认会自动配置事务管理器并开启事务支持。


   二、Spring AOP代理问题

1. 方法没有被public修饰

@Transactional注解只能作用于public修饰的方法上

Spring AOP 代理时,TransactionInterceptor (事务拦截器)在目标方法执行前后进行拦截,DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource的 computeTransactionAttribute 方法,获取Transactional 注解的事务配置信息。

此方法会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。

注意:protected、private 修饰的方法上使用 @Transactional 注解,虽然事务无效,但不会有任何报错。

解决方案:将当前方法访问级别更改为public。

4.同一个类中,方法内部调用
5.方法的访问权限不是oublic


三、底层数据库不支持

1. 数据库的存储引擎不支持事务

Spring事务的底层,还是依赖于数据库本身的事务支持。在MySQL中,MyISAM存储引擎是不支持事务的,InnoDB引擎才支持事务。因此开发阶段设计表的时候,确认你的选择的存储引擎是支持事务的。

四、Transactional配置问题
1.配置错误的@Transactional注解
2.事务超时时间设置过短
3.使用了错误的事务传播机制
4.rollbackFor属性配置错误

五、开发使用不当

1. 事务注解被覆盖导致事务失效
2.嵌套事务的坑
3.事务多线程调用
4.异常被捕获并处理了,没有重新抛出
5.手动抛了别的异常


参考链接:

https://juejin.cn/post/7179080622504149029
https://heapdump.cn/article/5542790

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

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

相关文章

android开发编译openssl源代码生成libcrypto.so和libssl.so两个动态库用于android ndk项目开发使用

openssl编译本篇文章的操作是在Linux环境之下,在虚拟机ubuntu 20版本上操作的步骤1. openssl下载解压tar包openssl下载地址:https://openssl-library.org/source/下载完解压:tar -zxvf openssl-3.3.2.tar.gz // 我这里下载openssl-3.3.2.tar.gz版本2. 编译openssl库,得到l…

MySQL下载、安装与配置

MySQL下载、安装与配置下载MySQL 1、进入MySQL官网 2、点击 Products,再点击 MySQL Community Server3、选择MySQL版本,点击 Go to Download Page4、点击 Download 下载MySQL安装程序5、点击 No thanks, just start my download,等待下载安装MySQL 1、双击运行下载的安装程序…

web端ant-design-vue Upload 手动实现文件上传使用小节

web端ant-design-vue Upload 手动实现文件上传使用小节。最近在项目开发中用到了手动实现文件上传的组件,之前都是自动上传把返回的文件信息保存到服务器。手动上传相对复杂一下,我把遇到的一些问题整理记录一下,有需要的朋友可以避免走弯路! 1、文件上传需要用formdata格式…

记一次k8s挂载configmap配置文件识别为文件夹的错误

错误表现 挂载.env为配置文件时被识别成一个文件夹而不是一个文件错误原因 创建configmap的时候原始文件使用的是env解决方式 创建configmap的时候需要使用的文件需要修改文件名为挂载的文件名一致 例如本次挂载的文件名是.env则需要在创建configmap的时候原始文件名修改为.evn…

开源项目更新|WPF/Uno Platform/WinUI 3三个版本的《英雄联盟客户端》

为了统一WPF/WinUI3/Uno仓库的项目架构,我们基于.NET Standard 2.0设计了一个可在所有平台上运行的框架,无需依赖第三方库。这个框架直接实现了项目分散化、模块化、视图注入、依赖注入、单例模式和MVVM等基于XAML的项目架构所需功能。采用这种方法,我们可以在不同版本(如WPF、…

简明线性回归算法中的最小二乘法

我们来通过一个具体的例子说明线性回归算法中最小二乘法如何确定模型参数。 示例:房价预测 假设我们想用房子的面积(平方英尺)来预测房价(美元)。我们有以下数据集:面积(平方英尺)房价(美元)800 150,0001000 200,0001200 210,0001500 280,0001. 建立模型 我们假设房价…

web端ant-design-vue Modal.info组件自定义icon和title使用小节

web端ant-design-vue Modal.info组件自定义icon和title整理小节,最近在项目中用到了自定义icon和title的功能,经过测试发现,如果自定义icon title会自动换行,尝试直接修改样式和穿透方式都没有效果,最后采取了一个巧妙的方式,将icon和title放在一个自定义组件内,完美解决…

Ewald求和在分子静电势能计算中的应用

本文介绍了Ewald求和计算方法在周期性边界条件下计算静电势能的方法。周期性的静电势函数并不是一个空间收敛的函数,通过Ewald求和可以将静电势切分为短程相互作用和长程相互作用,两项分别在实空间和倒易空间(或称傅里叶空间、k空间等)收敛。然后就可以进一步进行截断,用更…