Spring@Transactional事务注解

工作原理

基于AOP动态代理实现,Spring 通过 AOP 为使用 @Transactional 注解的方法创建代理对象。当调用被 @Transactional 注解标记的方法时,实际调用的是代理对象的方法。代理对象在方法调用前后织入事务管理逻辑,实现对事务的控制。

注解配置参数

propagation:事务传播行为

isolation:事务隔离级别

timeout:事务超时时间

readOnly:指定事务是否为只读事务

rollbackFor:指定能够触发事务回滚的异常类型

spring事务失效场景

1、未捕获异常: 如果一个事务方法中发生了未捕获的异常,并且异常未被处理或抛出,那么事务会失效。

2、抛出检查异常: 默认情况下,Spring对非受检异常(RuntimeException或其子类)进行回滚处理,这意味着当事务方法中抛出这些异常时,事务会回滚,遇到检查异常事务会失效。

3、事务传播属性设置不当: 如果在多个事务之间存在事务嵌套,且事务传播属性配置不正确,可能导致事务失效。特别是在方法内部调用有 @Transactional 注解的方法时要特别注意。

4、多数据源的事务管理: 如果在使用多数据源时,事务管理没有正确配置或者存在多个 @Transactional 注解时,可能会导致事务失效。

5、跨方法调用事务问题: 如果一个事务方法内部调用另一个方法,而这个被调用的方法没有 @Transactional 注解,这种情况下外层事务可能会失效。

6、事务在非public方法中失效: 如果 @Transactional 注解标注在私有方法上或者非 public 方法上,事务也会失效。

为什么@Transactional 修饰非public方法会导致事务失效

事务注解的底层原理是动态代理,无法代理非public方法,代理对象无法访问目标对象内部的private方法。

为什么方法内部捕获异常没有重新抛出会导致事务失效

方法内部捕获异常不抛出的话,异常就不会传播到方法外部,这样spring事务管理器就不会感知到异常,会认为事务正常执行从而无法回滚。

spring aop自调用问题

当某个方法被@Transactional修饰的时候,spring事务管理器只会在被其他类调用该方法的时候生效,如果是本类中的其他方法调用,就会失效。

这是因为 Spring AOP 工作原理决定的。因为 Spring AOP 使用动态代理来实现事务的管理,它会在运行的时候为带有 @Transactional 注解的方法生成代理对象,并在方法调用的前后应用事物逻辑。如果该方法被其他类调用我们的代理对象就会拦截方法调用并处理事务。但是在一个类中的其他方法内部调用的时候,我们代理对象就无法拦截到这个内部调用,因此事务也就失效了。

通过 AspectJ可以解决自调用问题,它是在编译期或类加载期将事务逻辑织入到类中,无论是否是自调用,事务都会生效。

spring支持的两种事务管理方式

编程式事务管理:通过 TransactionTemplate或者TransactionManager手动管理事务

声明式事务:基于@Transactional注解实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值