java事務(wù)回滾失敗問題分析
Spring-Java事物回滾失效處理最近在做項目中,無意間發(fā)現(xiàn)有個類在拋事物回滾操作,數(shù)據(jù)也正常的插入到數(shù)據(jù)庫當(dāng)中了,于是仔細(xì)查看看一下具體原因。
一切還是要從Java的檢查型異常和非檢查型異常說起。
那么什么是檢查型異常什么又是非檢查型異常呢?
最簡單的判斷點(diǎn)有兩個:
1.繼承自RuntimeException或Error的是非檢查型異常,而繼承自Exception的則是檢查型異常(當(dāng)然,RuntimeException本身也是Exception的子類)。
2.對非檢查型類異常可以不用捕獲,而檢查型異常則必須用try……catch語句塊進(jìn)行處理或者把異常交給上級方法處理,總之就是必須寫代碼處理它。
Java的異常結(jié)構(gòu)如下圖。其中直接繼承Exception的異常,必須捕獲,屬于檢查型異常。
再回過來看我的代碼:
1、方法名前面有
@Transactional
2、Spring的配置文件applicationContext-XXX.xml當(dāng)中也有Spring事物的相關(guān)配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="rollbackOnCommitFailure" value="true"></property> </bean>
但是為什么在Service層方法調(diào)用的時候,try……catch拋Exception異常已經(jīng)提交的事物卻沒有回滾?
查看相關(guān)spring的文檔后發(fā)現(xiàn),原來spring聲明式事務(wù)管理默認(rèn)對非檢查型異常和運(yùn)行時異常進(jìn)行事務(wù)回滾,而對檢查型異常則不進(jìn)行回滾操作。
代碼中try……catch拋出的Exception異常,屬于檢查型異常,Spring的框架默認(rèn)是不會進(jìn)行回滾的。
在編程中對非檢查型類異常可以不用捕獲,而檢查型異常則必須用try語句塊進(jìn)行處理或者把異常交給上級方法處理總之就是必須寫代碼處理它。
所以必須在service捕獲異常,然后再次手動throw一個非檢查型異常,這樣事務(wù)方才起效。例如:
try{ ………… } catch (Exception e) { ………… throw new BusinessException(e.getMessage()); }
當(dāng)然我們還有更簡便的方法來解決這個問題,那就是通過注解參數(shù)改變默認(rèn)的回滾方式。
在@Transaction注解中定義了noRollbackFor和RollbackFor來指定某種異常是否回滾。
使用例:
@Transaction(noRollbackFor=RuntimeException.class)
@Transaction(RollbackFor=Exception.class)
所以上述的問題可以直接將@Transaction添加回滾參數(shù)@Transaction(RollbackFor=Exception.class),這樣就改變了默認(rèn)的事務(wù)處理方式。
啟示:
這就要求我們在自定義異常的時候,讓自定義的異常繼承自RuntimeException,這樣拋出的時候才會被Spring默認(rèn)的事務(wù)處理準(zhǔn)確處理。
總結(jié)
以上就是本文關(guān)于java事務(wù)回滾失敗問題分析的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
相關(guān)文章
SpringBoot+Dubbo+Seata分布式事務(wù)實(shí)戰(zhàn)詳解
這篇文章主要介紹了SpringBoot+Dubbo+Seata分布式事務(wù)實(shí)戰(zhàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Java+Spring+MySql環(huán)境中安裝和配置MyBatis的教程
這篇文章主要介紹了Java+Spring+MySql環(huán)境中安裝和配置MyBatis的教程,MyBatis一般被用來增強(qiáng)數(shù)據(jù)庫操作,文中對MyBatis的主配置文件有較為詳細(xì)的講解,需要的朋友可以參考下2016-04-04SpringBoot實(shí)現(xiàn)動態(tài)多線程并發(fā)定時任務(wù)
這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)動態(tài)多線程并發(fā)定時任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05SpringCloud2020 bootstrap 配置文件失效的解決方法
這篇文章主要介紹了SpringCloud2020 bootstrap 配置文件失效的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02Spring Boot使用RestTemplate消費(fèi)REST服務(wù)的幾個問題記錄
這篇文章主要介紹了Spring Boot使用RestTemplate消費(fèi)REST服務(wù)的幾個問題記錄,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS)
本篇文章主要介紹了淺談spring-boot 允許接口跨域并實(shí)現(xiàn)攔截(CORS),具有一定的參考價值,有興趣的可以了解一下2017-08-08Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例
這篇文章主要介紹了Mybatis 動態(tài)sql if 判讀條件等于一個數(shù)字的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11