溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring事務(wù)失效之怎么解決關(guān)于this調(diào)用的問題

發(fā)布時間:2021-11-01 09:13:27 來源:億速云 閱讀:876 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“Spring事務(wù)失效之怎么解決關(guān)于this調(diào)用的問題”,在日常操作中,相信很多人在Spring事務(wù)失效之怎么解決關(guān)于this調(diào)用的問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring事務(wù)失效之怎么解決關(guān)于this調(diào)用的問題”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

  • PROPAGATION_REQUIRED: 如果存在一個事務(wù),則支持當前事務(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ù)失效之怎么解決關(guān)于this調(diào)用的問題”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI