工作原理
基于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注解实现



413

被折叠的 条评论
为什么被折叠?



