一、@Transactional 的原理

@Transactional 注解的原理是基于 Spring 框架中的事务管理机制。它利用了 Spring 的 AOP(面向切面编程)技术来实现对事务的管理。

在 Spring 中使用 @Transactional 注解时,Spring 会通过代理对象来实现事务管理

二、不必要的使用场景

1. 无需事务的方法

  • 问题描述:在只包含查询或只读操作的方法上使用@Transactional是不必要的,因为这些操作不需要事务管理。

  • 详细说明:虽然在这些方法上添加@Transactional不会对系统造成太大影响,但从代码规范和性能优化的角度来看,应该避免不必要的事务开销

2. 事务范围过大

  • 问题描述:将@Transactional注解应用于整个类或抽象类,导致所有方法都被事务管理,这可能导致不必要的性能开销和事务管理的复杂性。

  • 详细说明:应该根据具体方法的业务需求来决定是否使用事务,而不是一概而论地对整个类应用事务管理。

三、不生效的场景

1. 非public方法

  • 问题描述:在非public方法上使用@Transactional不会生效,因为Spring AOP无法代理私有方法。

  • 详细说明:Spring AOP通过代理方式实现@Transactional注解的功能,而非public方法无法被代理,因此事务管理不会生效。

2. finalstatic方法:

  • 问题描述:在finalstatic方法上使用@Transactional不会生效,因为这些方法无法被Spring代理。

  • 详细说明static方法属于类而非实例,而final方法不能被子类重写,因此Spring无法通过代理这些方法来实现事务管理。

3. Bean未被Spring管理:

  • 问题描述:如果Bean没有被Spring管理,@Transactional不会生效。

  • 详细说明:确保Bean被Spring管理,可以通过加上@Service@Component等注解来实现。

四、生效但不触发回滚

1. 错误的传播属性:

  • 问题描述@Transactionalpropagation属性配置错误可能导致事务不回滚。

  • 示例代码

     @Transactional(propagation = Propagation.REQUIRED)
     public String testMerge() {
         testAService.testA();
         testBService.testB();
         return "ok";
     }
  • 详细说明:理解不同propagation属性的含义和适用场景,确保事务在预期的范围内生效。

2. 异常被捕获:

  • 问题描述:在方法内部捕获异常并处理,而不重新抛出,会导致事务无法回滚。

  • 示例代码

     @Transactional
     public String testMerge() {
         try {
             testAService.testA();
             testBService.testB();
         } catch (Exception e) {
             log.error("testMerge error:{}", e);
         }
         return "ok";
     }
  • 详细说明:为了确保事务能够正确回滚,应该在捕获异常后重新抛出一个RuntimeException或Error类型的异常。

3. 事务无法捕获的异常:

  • 问题描述:默认情况下,事务只回滚RuntimeException及其子类和Error类型的异常。其他类型的异常,如SQLException,不会触发回滚。

  • 示例代码

     java 代码解读复制代码@Transactional(rollbackFor = Exception.class)
     public String testMerge() throws Exception {
         try {
             testAService.testA();
             testBService.testB();
         } catch (Exception e) {
             log.error("testMerge error:{}", e);
             throw new Exception(e);
         }
         return "ok";
     }
  • 详细说明:通过在@Transactional注解中指定rollbackFor属性,可以扩大事务回滚的范围,包括非运行时异常。

文章作者: 落叶知秋
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落叶知秋
疑难杂症 面试相关 学习笔记
喜欢就支持一下吧