1. 程式人生 > 其它 >Spring中同一個service中方法相互呼叫事務不生效問題解決方案

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) 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("錯誤"); } }


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