這篇文章主要介紹“Spring事務失效之怎么解決關于this調用的問題”,在日常操作中,相信很多人在Spring事務失效之怎么解決關于this調用的問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring事務失效之怎么解決關于this調用的問題”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
PROPAGATION_REQUIRED: 如果存在一個事務,則支持當前事務。如果沒有事務則開啟事務;
PROPAGATION_REQUIRES_NEW:總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起;
問題:
Spring中一個沒有事務的方法A調用一個默認事務(PROPAGATION_REQUIRED)的方法B時,如果使用this調用方法B,方法B拋出RuntimeException,此時方法B事務未生效,不會回滾。
@Service
public class EmployeeService {
@Autowired
private EmployeeDao employeeDao;
public void save(){
try {
this.saveEmployee(); //此處this調用不會開啟事務,數據會被保存
}catch (Exception e){
e.printStackTrace();
}
}
@Transactional(propagation = Propagation.PROPAGATION_REQUIRED)
//此處無論是PROPAGATION_REQUIRED還是PROPAGATION_REQUIRES_NEW,事務均不生效
public void saveEmployee(){
Employee employee = new Employee();
employee.setName("zhangsan");
employee.setAge("26";
employeeDao.save(employee);
throw new RuntimeException();
}
}問題原因:
JDK的動態代理。只有被動態代理直接調用時才會產生事務。在SpringIoC容器中返回的調用的對象是代理對象而不是真實的對象。而這里的this是EmployeeService真實對象而不是代理對象。
解決辦法:
方法1、在方法A上開啟事務,方法B不用事務或默認事務,并在方法A的catch中throw new RuntimeException();(在沒指定rollbackFor時,默認回滾的異常為RuntimeException),這樣使用的就是方法A的事務。(一定要throw new RuntimeException();否則異常被捕捉處理,同樣不會回滾。)如下:
@Transactional() //開啟事務
public void save(){
try {
this.saveEmployee(); //這里this調用會使事務失效,數據會被保存
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException();
}
}方法2、方法A上可以不開啟事務,方法B上開啟事務,并在方法A中將this調用改成動態代理調用(AopContext.currentProxy()),如下:
public void save(){
try {
EmployeeService proxy =(EmployeeService) AopContext.currentProxy();
proxy.saveEmployee();
}catch (Exception e){
e.printStackTrace();
}
}到此,關于“Spring事務失效之怎么解決關于this調用的問題”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。