spring,同一个类中有a,b两个方法a加了事务,b没加事务,a调用本类b方法,b方法中报错了a会回滚吗
时间: 2023-08-28 07:49:45 浏览: 56
在Spring框架中,同一个类中有a,b两个方法a加了事务,b没加事务,a调用本类b方法,b方法中报错了a会回滚。
如果a方法使用了Spring的事务管理,而b方法没有使用事务管理,则在a方法中调用b方法时,Spring会将b方法的执行视为一个新的事务。如果b方法中出现异常,则只会回滚b方法中对数据库的操作,而不会回滚a方法中的操作。因此,a方法中的事务将会提交。
如果希望在a方法中调用b方法时,将b方法的执行视为a方法的一部分,则可以使用AspectJ来实现。具体来说,可以在a方法上添加@Transaction注解,并设置propagation属性为REQUIRED,表示将b方法的执行视为a方法的一部分,这样b方法中出现异常时,整个事务都会回滚。
相关问题
spring 调用本类方法 事务失效场景
在Spring中,当一个类的方法被另一个方法调用时,如果两个方法都属于同一个类,且在同一个类的实例中被调用,那么默认情况下是不会发生事务的传播的,即调用本类方法不会触发事务。
具体来说,当一个类的方法A被另一个方法B调用时,如果方法A上标注了@Transactional注解,而方法B没有标注@Transactional注解,那么在方法B中调用方法A时,事务是不会起作用的。这是因为 Spring的事务是基于代理实现的,事务的控制是通过AOP(面向切面编程)实现的。而在同一个类中的方法调用是通过普通的Java方法调用,不会经过AOP的处理,所以事务的控制也无法传播到被调用的方法中。
为了解决这个问题,我们可以通过两种方式来保证事务传播:
1. 将方法B也标注为@Transactional,这样在方法B中调用方法A时,事务会正常起作用。
2. 将方法A抽离出来,放在单独的一个类中,而不是同一个类中的另一个方法调用,这样事务也会正常起作用。
总结起来,调用本类方法时,事务失效的场景是:在同一个类中的方法调用。为了解决这个问题,可以将调用的方法也标注为@Transactional,或者将该方法抽离出来放到单独的类中。
@Transactional方法A调用 @Transactional方法B 会有什么问题
当使用@Transactional注解时,方法会被包装在一个事务中。如果方法A调用了方法B,并且两个方法都被@Transactional注解修饰,那么事务将无法正常工作。这是因为Spring默认使用基于代理的AOP来实现@Transactional注解的功能,而代理只能拦截外部调用,无法拦截类内部方法的调用。
在你提供的引用中,方法A没有@Transactional注解,而方法B有@Transactional注解。当方法A调用方法B时,事务不会起作用,因为方法A内部的方法调用无法被代理拦截。
在你提供的引用中,方法A调用了方法B,方法B调用了方法C,并且方法C被@Transactional注解修饰。然而,由于方法A内部的方法调用无法被代理拦截,所以方法C的事务也无法起作用。即使方法C抛出了异常,事务也不会回滚。
为了解决这个问题,可以将@Transactional注解放在类级别上,而不是方法级别上。这样,整个类的所有方法都会被包装在同一个事务中,无论是外部调用还是内部调用。
另外,还可以通过将方法C提取到一个独立的类中,并通过依赖注入的方式调用该类的方法,来实现事务的正常工作。