事务切面不生效本质是@transactional未触发代理增强;需验证方法为public非static/final、类被spring管理、调用走代理链(禁自调用)、异常符合回滚条件、事务管理器正确配置。

事务切面不生效,本质是 Spring 的 @Transactional 没触发代理增强。它不是“配置错了”,而是“没走到代理链上”。排查必须从代理机制出发,一层层验证调用路径是否合规。
看方法是否被代理正确拦截
Spring 事务基于 AOP 代理(JDK 或 CGLIB),只对 public 方法 生效。非 public(private/protected/包级)、static、final 方法,注解直接被忽略。
- 检查目标方法修饰符:必须是 public,且不能被
final或static修饰 - 确认类是否被 Spring 管理:必须是
@Service、@Component等托管 Bean,普通 new 出来的对象无效 - 若用 JDK 代理(类实现接口),确保调用方是通过接口类型引用的;若用 CGLIB,注意类不能是
final
查调用是否绕过了代理对象
最常见失效原因:同一个类中,this.methodB() 调用另一个加了 @Transactional 的方法——this 是原始对象,不是代理对象,事务切面根本不会执行。
- 自查代码是否存在“自调用”:如
public void a() { this.b(); },其中b()有事务注解 - 解决方案有三种:
- 拆分逻辑到不同 Service 类(推荐,职责清晰)
- 自我注入:
@Autowired private UserService self;,然后调用self.b() - 启用暴露代理:
@EnableAspectJAutoProxy(exposeProxy = true),再用AopContext.currentProxy()获取代理后调用
验异常是否符合回滚条件
事务默认只对未捕获的 RuntimeException 及其子类、Error 回滚。受检异常(如 IOException)或被 try-catch 吞掉的异常,都不会触发回滚。
- 检查方法内是否有
catch块但未重新抛出异常 - 若需对受检异常回滚,显式指定:
@Transactional(rollbackFor = IOException.class) - 避免在事务方法里
catch (Exception e) { log.error(...); }后静默返回
核事务管理器与数据源绑定
没有正确配置 PlatformTransactionManager,或者多数据源下未指定对应事务管理器,事务切面会“无事可做”。
- 确认配置类中已声明
@Bean类型为DataSourceTransactionManager,且参数传入的是目标DataSource - 多数据源场景下,每个
@Transactional必须明确指定transactionManager属性,例如:@Transactional(transactionManager = "slaveTxManager") - 检查
@Primary是否误标在非主事务管理器上,导致默认选错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











