1. 程式人生 > >service中配置的事務回滾不起作用

service中配置的事務回滾不起作用

這兩天一直在研究一個東西,關於事務回滾的,因為我突然發現我們專案竟然不支援,不支援,但是我們整個事務的配置檔案都是有的。

關於事務配置,我就不再多闡述了,可以參考這篇文章: 事務回滾配置

下面說我遇到的問題吧,就是所有的配置都完成了,但就是不起作用,丟擲了RuntimeException就是不會滾,資料庫操作該執行還是執行了。最後才想到會不會是資料庫表引擎的問題,立馬去看,果然,表引擎都是myisam,我的天,把引擎改一下,立馬好了。

下面總結一下,在確認配置檔案都配置好,所有工作都無誤的情況下還是不支援事務時的幾個檢查方面:

使用@Transactional註解的回滾方式的檢查方面

1、看方法是否是public的,註解方式預設只在public修飾的方法上起作用,

protected、private 或者 default 修飾的方法上使用@Transactional時不會報錯,但是事務設定不起作用。

2、檢查是不是同一個類中方法的呼叫。(比如同一個方法中存在A和B兩個方法,A方法去呼叫B方法)

基於spring aop的配置回滾方式的檢查方面

1、配置檔案中的aop相關配置,看expression配置的路徑是否可以掃描到你的方法。

<aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.test.service.impl..*.*(..))" />
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>

上面程式碼中我配置的是 掃描com.test.service.impl 包及其子包中的所有的方法。

順便給出execution表示式常見的相關配置說明:

execution(public * *(..))                      任意的公共方法

execution(* set*(..))                          任何以set開頭的方法

execution( * com.test.service.impl.*.*(..))       com.test.service.impl包下的任意方法

execution( * com.test.service.impl..*.*(..))      com.test.service.impl包及其子包下的任意方法

下面是以上兩種配置方式都可能出現不回滾的檢查方面:

1、資料庫引擎要支援事務,如果是MySQL,注意表要使用支援事務的引擎,比如innodb,如果是myisam,事務配置是不起作用的。

2、看service是否進行了try...catch...但是沒有在catch塊中繼續丟擲異常。

以下程式碼進行了try...catch...將異常捕獲了,所以spring沒法識別你的異常,當然也不會進行回滾。

public void test () { 
    try{
        insert(a);
        delete(b)
    } catch {
        System.out.println("不會回滾!!!");
    }
}

    正解如下,進行了try...catch...之後再catch塊中繼續進行異常的丟擲,這樣就可以實現回滾。

public void test () { 
    try{
        insert(a);
        delete(b)
    } catch {       
         throw new RuntimeException("操作失敗!!!");
    }
}

好了,到此結束,自己問題也解決了,希望簡單的總結能幫到一個兩個的同行!

此文為原創,歡迎轉載,轉載請註明出處,謝謝微笑