Spring事務(wù)失效的一種原因關(guān)于this調(diào)用的問題
PROPAGATION_REQUIRED: 如果存在一個事務(wù),則支持當(dāng)前事務(wù)。如果沒有事務(wù)則開啟事務(wù);PROPAGATION_REQUIRES_NEW:總是開啟一個新的事務(wù)。如果一個事務(wù)已經(jīng)存在,則將這個存在的事務(wù)掛起;
問題:
Spring中一個沒有事務(wù)的方法A調(diào)用一個默認事務(wù)(PROPAGATION_REQUIRED)的方法B時,如果使用this調(diào)用方法B,方法B拋出RuntimeException,此時方法B事務(wù)未生效,不會回滾。
@Service
public class EmployeeService {
@Autowired
private EmployeeDao employeeDao;
public void save(){
try {
this.saveEmployee(); //此處this調(diào)用不會開啟事務(wù),數(shù)據(jù)會被保存
}catch (Exception e){
e.printStackTrace();
}
}
@Transactional(propagation = Propagation.PROPAGATION_REQUIRED)
//此處無論是PROPAGATION_REQUIRED還是PROPAGATION_REQUIRES_NEW,事務(wù)均不生效
public void saveEmployee(){
Employee employee = new Employee();
employee.setName("zhangsan");
employee.setAge("26";
employeeDao.save(employee);
throw new RuntimeException();
}
}
問題原因:
JDK的動態(tài)代理。只有被動態(tài)代理直接調(diào)用時才會產(chǎn)生事務(wù)。在SpringIoC容器中返回的調(diào)用的對象是代理對象而不是真實的對象。而這里的this是EmployeeService真實對象而不是代理對象。
解決辦法:
方法1、在方法A上開啟事務(wù),方法B不用事務(wù)或默認事務(wù),并在方法A的catch中throw new RuntimeException();(在沒指定rollbackFor時,默認回滾的異常為RuntimeException),這樣使用的就是方法A的事務(wù)。(一定要throw new RuntimeException();否則異常被捕捉處理,同樣不會回滾。)如下:
@Transactional() //開啟事務(wù)
public void save(){
try {
this.saveEmployee(); //這里this調(diào)用會使事務(wù)失效,數(shù)據(jù)會被保存
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException();
}
}
方法2、方法A上可以不開啟事務(wù),方法B上開啟事務(wù),并在方法A中將this調(diào)用改成動態(tài)代理調(diào)用(AopContext.currentProxy()),如下:
public void save(){
try {
EmployeeService proxy =(EmployeeService) AopContext.currentProxy();
proxy.saveEmployee();
}catch (Exception e){
e.printStackTrace();
}
}
到此這篇關(guān)于spring事務(wù)調(diào)用失效問題的文章就介紹到這了,更多相關(guān)spring事務(wù)調(diào)用失效問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 下數(shù)據(jù)業(yè)務(wù)邏輯開發(fā)技術(shù) JOOQ 和 SPL
這篇文章主要為大家介紹了Java 下數(shù)據(jù)業(yè)務(wù)邏輯開發(fā)技術(shù) JOOQ 和 SPL詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
用java實現(xiàn)的獲取優(yōu)酷等視頻縮略圖的實現(xiàn)代碼
想獲取優(yōu)酷等視頻縮略圖,在網(wǎng)上沒有找到滿意的資料,參考了huangdijia的PHP版工具一些思路,寫了下面的JAVA版代碼。。其實也可以做成JS版的2013-05-05
部署springboot項目到云服務(wù)器的兩種方式(jar+war)
本文主要介紹了部署springboot項目到云服務(wù)器的兩種方式,主要介紹了jar和war兩種方式,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12

