事务失效场景
1. 没有被 Spring 管理
常见原因:
- 类没有被Spring容器扫描到(未添加@Component、@Service等注解)
- 配置文件未正确配置扫描路径
- 方法调用方式不当(同类内部调用)
- 使用new关键字实例化对象
解决办法:
- 确保类被正确注解并处于Spring扫描路径下
- 通过@Autowired获取Bean实例,避免直接new
- 对于同类方法调用,将事务方法抽取到另一个Bean中
2. 没有启动事务管理器
在 Spring Boot 应用中,事务管理器会自动配置:
- 添加了 spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa 依赖时
- Spring Boot 会自动创建 DataSourceTransactionManager 实例
3. 事务方法修饰不当
final 方法的问题:
final方法不能被重写- Spring 的动态代理无法为 final 方法生成代理
static 方法的问题:
static方法属于类级别- Spring 的事务管理是基于实例的代理,无法作用于静态方法
解决方案:
- 避免在需要事务管理的方法上使用
final或static修饰符
4. 同一类中内部调用
Spring 事务是通过代理机制实现的,同一类中内部调用会绕过代理。
解决方案:
- 拆分类(推荐):将事务方法放到另一个Service中
- 自我注入:在类中注入自身实例
- 使用AopContext:通过AopContext获取当前代理对象
// 自我注入方式
@Service
public class SomeService {
@Autowired
private SomeService self;
public void methodA() {
self.methodB(); // 通过代理调用
}
@Transactional
public void methodB() {
// 业务逻辑
}
}