您好,登錄后才能下訂單哦!
小編給大家分享一下java事務回滾失敗怎么辦,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
Spring-Java事物回滾失效處理最近在做項目中,無意間發現有個類在拋事物回滾操作,數據也正常的插入到數據庫當中了,于是仔細查看看一下具體原因。
一切還是要從Java的檢查型異常和非檢查型異常說起。
那么什么是檢查型異常什么又是非檢查型異常呢?
最簡單的判斷點有兩個:
1.繼承自RuntimeException或Error的是非檢查型異常,而繼承自Exception的則是檢查型異常(當然,RuntimeException本身也是Exception的子類)。
2.對非檢查型類異常可以不用捕獲,而檢查型異常則必須用try……catch語句塊進行處理或者把異常交給上級方法處理,總之就是必須寫代碼處理它。
Java的異常結構如下圖。其中直接繼承Exception的異常,必須捕獲,屬于檢查型異常。
再回過來看我的代碼:
1、方法名前面有
@Transactional
2、Spring的配置文件applicationContext-XXX.xml當中也有Spring事物的相關配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="rollbackOnCommitFailure" value="true"></property> </bean>
但是為什么在Service層方法調用的時候,try……catch拋Exception異常已經提交的事物卻沒有回滾?
查看相關spring的文檔后發現,原來spring聲明式事務管理默認對非檢查型異常和運行時異常進行事務回滾,而對檢查型異常則不進行回滾操作。
代碼中try……catch拋出的Exception異常,屬于檢查型異常,Spring的框架默認是不會進行回滾的。
在編程中對非檢查型類異常可以不用捕獲,而檢查型異常則必須用try語句塊進行處理或者把異常交給上級方法處理總之就是必須寫代碼處理它。
所以必須在service捕獲異常,然后再次手動throw一個非檢查型異常,這樣事務方才起效。例如:
try{ ………… } catch (Exception e) { ………… throw new BusinessException(e.getMessage()); }
當然我們還有更簡便的方法來解決這個問題,那就是通過注解參數改變默認的回滾方式。
在@Transaction注解中定義了noRollbackFor和RollbackFor來指定某種異常是否回滾。
使用例:
@Transaction(noRollbackFor=RuntimeException.class)
@Transaction(RollbackFor=Exception.class)
所以上述的問題可以直接將@Transaction添加回滾參數@Transaction(RollbackFor=Exception.class),這樣就改變了默認的事務處理方式。
啟示:
這就要求我們在自定義異常的時候,讓自定義的異常繼承自RuntimeException,這樣拋出的時候才會被Spring默認的事務處理準確處理。
看完了這篇文章,相信你對“java事務回滾失敗怎么辦”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。