1. 程式人生 > >spring 事務不起作用 問題彙總

spring 事務不起作用 問題彙總

 今早接手了別人的專案,測試了一下事務,發覺不起作用,檢查了N久程式碼,才發覺是springMVC 配置檔案裡context:component-scan重複掃碼了service,導致事務不起作用(建議MVC scan只掃描action或Controller),下面根據網上的一些資料,整理了一下事務不起作用的幾個點:

1、首先使用如下程式碼 確認你的bean 是代理物件嗎?

AopUtils.isAopProxy()

AopUtils.isCglibProxy() //cglib

AopUtils.isJdkDynamicProxy() //jdk動態代理

2、如果是aop代理,那麼說明代理成功,那麼可能是如使用mysql且引擎是MyISAM造成的(因為不支援事務),改成InnoDB即可。

3、 如果你是基於類的代理,而非介面,如果想代理父類裡的,可以用

execution(* com.sishuok.es..service..+.(..))

4、spring事務預設只在發生未被捕獲的 RuntimeExcetpion時才回滾,所以,得檢查service方法中有沒有使用try catch,如果使用了try catch,在catch中最後加上throw new runtimeexcetpion(),這樣程式異常時才能被aop捕獲進而回滾,或在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動回滾,這樣上層就無需去處理異常(最好不要在service中try catch)

5.針對預設 只在發生未被捕獲RuntimeExcetpion時才回滾的情況,可以重設一下exception回滾策略
rollback-for=”java.lang.Exception”

 <tx:advice id="tx"  transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="insert*"
propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="find*" read-only="true" /> <tx:method name="get*" read-only="true" /> <tx:method name="select*" read-only="true" /> <tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice>