【轉】@Transactional 注解不生效原因


1、檢查你的方法是不是public的。@Transactional注解只能應用到public可見度的方法上,如果應用在protected、private或者package可見度的方法上,也不會報錯,不過事務設置不會起作用。

2、檢查你的異常類型是不是unchecked異常。默認情況下,Spring會對unchecked異常進行事務回滾,如果是checked異常則不回滾。如空指針異常、算術異常等,會被回滾;文件讀寫、網絡出問題,spring就沒法回滾了。如果你想check異常也回滾怎么辦,注解上面寫明異常類型即可:

@Transactional(rollbackFor = Exception.class)

類型的還有norollbackFor,自定義不回滾的異常。

3、是否在service中進行了try...catch的操作,由於已經被捕獲異常,故事務也不會回滾。如果非要在service中try...catch異常,又想要事務回滾,可在catch塊中拋出運行時異常:

try{
    ....  
}catch(Exception e){
    logger.error("",e);
    throw new RuntimeException;
}

這種方法有個不足之處,就是不能在catch塊中存在return子句,若想捕獲異常時回滾事務,同時返回提示信息,可以使用手動回滾:

try{
    ...
}catch(Exception e){
    logger.error("",e);
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    return ERROR_MESSAGE;
}

PS:另外說明一下,在controller層捕獲了service層的異常,事務還會回滾嗎?答案是會的,只要你service層拋出了異常,並且你加的事務可以處理這個異常,也就是rollbackFor = Exception.class這個符合你拋出的異常,不管外面有沒有捕獲都可以回滾。

4、是否開啟了對注解的解析:

<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          id="transactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

5、數據庫引擎要支持事務,如果是mysql,注意表要使用支持事務的引擎,比如innodb,如果是myisam,事務是不起作用的。

6、spring是否掃描到你這個包,如下是掃描到org.test下面的包:

<context:component-scan base-package="org.test" ></context:component-scan>

7、檢查是不是同一個類中的方法調用(如A方法無@Transactional注解,調用了一個有@Transactional注解的方法),這樣事務也是不生效的。原因可參照如下文章:

  https://blog.csdn.net/levae1024/article/details/82998386

  https://blog.csdn.net/gx_hxl/article/details/80808088

  https://blog.csdn.net/m0_38027656/article/details/84190949

 

參考:

@Transactional回滾不生效的原因

SpringMVC在controller層捕獲了service層的異常,事務還會回滾嗎


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM