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 代理,出现事务失效的情况。