Spring中同一個service中方法相互呼叫事務不生效問題解決方案
https://blog.csdn.net/panchao888888/article/details/82866315
問題描述:我們在用Spring框架開發Web專案過程中,經常需要用同一個service中的一個方法呼叫另一個方法,如果此時呼叫方沒有新增事務註解@Transactional,而在被呼叫方新增事務註解@Transactional,當被呼叫方法中出現異常,這時候會發現事務並沒有回滾,事務註解@Transactional沒有起作用。
分析原因:
我們知道Spring中事務管理是使用AOP代理技術實現的,目標物件自身並沒有事務管理功能的,而是通過代理物件動態增強功能對事務進行增強的。因此當我們在同一個service類中通過一個方法呼叫另一個方法時,是通過目標物件this物件呼叫的,目標物件自身並沒有事務管理功能,因此事務不能生效。
解決方案:
1.使用xml配置方式暴漏代理物件,然後在service中通過代理物件AopContext.currentProxy()去呼叫方法。
xml配置
<aop:aspectj-autoproxy expose-proxy="true"/>
service呼叫
@Service public class HelloWorldServiceImpl implements HelloWorldService { @Autowired private BlogRepository blogRepository; @Override public void a(BlogEntity blogEntity) throwsException { ((HelloWorldService) AopContext.currentProxy()).b(blogEntity); } @Transactional(rollbackFor = Exception.class) @Override public void b(BlogEntity blogEntity) throws Exception { blogRepository.save(blogEntity); throw new Exception("錯誤"); } }
2.在java配置類上添加註解@EnableAspectJAutoProxy(exposeProxy = true)方式暴漏代理物件,然後在service中通過代理物件AopContext.currentProxy()去呼叫方法。
java配置類
/** * @Author: PanChao * @Description: * @Date: Created in 13:14 2018/9/27 */ @Configuration @EnableAspectJAutoProxy(exposeProxy = true) public class AppConfig { } service呼叫 @Service public class HelloWorldServiceImpl implements HelloWorldService { @Autowired private BlogRepository blogRepository; @Override public void a(BlogEntity blogEntity) throws Exception { ((HelloWorldService) AopContext.currentProxy()).b(blogEntity); } @Transactional(rollbackFor = Exception.class) @Override public void b(BlogEntity blogEntity) throws Exception { blogRepository.save(blogEntity); throw new Exception("錯誤"); } }
3.(不推薦)在service中自動裝配service自身,然後同過裝配物件呼叫。
@Service public class HelloWorldServiceImpl implements HelloWorldService { @Autowired private BlogRepository blogRepository; @Autowired private HelloWorldService helloWorldService; @Override public void a(BlogEntity blogEntity) throws Exception { helloWorldService.b(blogEntity); } @Transactional(rollbackFor = Exception.class) @Override public void b(BlogEntity blogEntity) throws Exception { blogRepository.save(blogEntity); throw new Exception("錯誤"); } }
通過上述三種方法任意一種即可解決該問題,推薦使用第一二種方法。
————————————————
版權宣告:本文為CSDN博主「潘超部落格」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/panchao888888/article/details/82866315