事务失效场景

1. 没有被 Spring 管理

常见原因

  1. 类没有被Spring容器扫描到(未添加@Component、@Service等注解)
  2. 配置文件未正确配置扫描路径
  3. 方法调用方式不当(同类内部调用)
  4. 使用new关键字实例化对象

解决办法

  1. 确保类被正确注解并处于Spring扫描路径下
  2. 通过@Autowired获取Bean实例,避免直接new
  3. 对于同类方法调用,将事务方法抽取到另一个Bean中

2. 没有启动事务管理器

在 Spring Boot 应用中,事务管理器会自动配置:

  • 添加了 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 依赖时
  • Spring Boot 会自动创建 DataSourceTransactionManager 实例

3. 事务方法修饰不当

final 方法的问题

  • final 方法不能被重写
  • Spring 的动态代理无法为 final 方法生成代理

static 方法的问题

  • static 方法属于类级别
  • Spring 的事务管理是基于实例的代理,无法作用于静态方法

解决方案

  • 避免在需要事务管理的方法上使用 finalstatic 修饰符

4. 同一类中内部调用

Spring 事务是通过代理机制实现的,同一类中内部调用会绕过代理。

解决方案

  1. 拆分类(推荐):将事务方法放到另一个Service中
  2. 自我注入:在类中注入自身实例
  3. 使用AopContext:通过AopContext获取当前代理对象
// 自我注入方式
@Service
public class SomeService {
    @Autowired
    private SomeService self;

    public void methodA() {
        self.methodB();  // 通过代理调用
    }

    @Transactional
    public void methodB() {
        // 业务逻辑
    }
}