Spring 事务踩坑记录
Spring 事务踩坑记录
环境
- JDK 1.8
- Spring FrameWork 4.2.5
问题简述
有 service 方法如下,doSync()和doSyncSingle()被@Transcational注解。doSync()是doSyncSingle()的包装,每一个doSyncSingle()单独作为一个原子化操作。
| 1 | 
 | 
当实际运行时观察数据库发现,发生异常时事务并没有回滚,出现了状态不一致的情况。
排查后发现,doSyncSingle()并没有受到事务控制。
@Transcational注解在运行时发生了什么
Spring 的 @Transactional注解实际上是通过 AOP 代理的。
如果doSyncSingle()是在同一个类中的另一个方法doSync()用的,此时并没有触发 AOP,那么事务不会生效。
因为 Spring 的代理机制是基于类的代理,而不是基于实例的代理。当在同一个类中调用带有@Transactional注解的方法doSyncSingle()时,实际上是通过this调用的,而不是通过代理对象调用的,因此事务注解不会生效。
可能的解决方案
将doSyncSingle()移动到另一个 Service
创建一个新的 Service 文件,将doSyncSingle()移动到新文件中,使用该Service去调用它。
使用当前代理对象来调用doSyncSingle()
使用AopContext.curentProxy()获取当前代理对象,然后使用它返回的代理对象去调用doSyncSingle()`
| 1 | 
 | 
总结
使用 Spring 事务时需要注意,通过 AOP 代理的类去调用。直接在同一个类中调用会绕过 AOP 代理,出现事务失效的情况。