Spring AOP宣告式事務異常回滾

2021-06-21 02:15:18 字數 1867 閱讀 1171

**:

近日測試用例,發現這樣乙個現象:

在業務**中,有如下兩種情況,比如:

throw new runtimeexception("************");

事物回滾

throw new exception("************"); 事物沒有回滾

自以為很了解事物,或許時間久遠的緣故,沒分析出來何故,遂查閱了下資料,寫下了如下的內容,供參考:

1).spring的aop即宣告式事務管理預設是針對unchecked exception回滾。就是預設對runtimeexception()異常或是其子類進行事務回滾;checked異常,即exception可try{}捕獲的不會回滾,如果使用try-catch捕獲丟擲的unchecked異常後沒有在catch塊中採用頁面硬編碼的方式使用springapi對事務做顯式的回滾,則事務不會回滾, 「將異常捕獲,並且在catch塊中不對事務做顯式提交=生吞掉異常」 ,要想捕獲非執行時異常則需要如下配置:

解決辦法:

1.在針對事務的類中丟擲runtimeexception異常,而不是丟擲exception。

2.在txadive中增加rollback-for,裡面寫自己的exception,例如自己寫的exception:

id="txadvice" transaction-manager="transactionmanager">

name="*" rollback-for="com.cn.untils.exception.xyzexception"/>

或者定義不會滾的異常

id="txadvice">

name="update*" no-rollback-for="ioexception"/>

name="*"/>

2).spring的事務邊界是在呼叫業務方法之前開始的,業務方法執行完畢之後來執行commit or rollback(spring預設取決於是否丟擲runtime異常).

如果丟擲runtime exception 並在你的業務方法中沒有catch到的話,事務會回滾。

一般不需要在業務方法中catch異常,如果非要catch,在做完你想做的工作後(比如關閉檔案等)一定要丟擲runtime exception,否則spring會將你的操作commit,這樣就會產生髒資料.所以你的catch**是畫蛇添足。

如:try catch(exception e)

由此可以推知,在spring中如果某個業務方法被乙個 整個包裹起來,則這個業務方法就等於脫離了spring事務的管理,因為沒有任何異常會從業務方法中丟擲!全**獲併吞掉,導致spring異常丟擲觸發事務回滾策略失效。

不過,如果在catch**塊中採用頁面硬編碼的方式使用springapi對事務做顯式的回滾,這樣寫未嘗不可。

3).基於註解的事物:

transactional的異常控制,預設是check exception 不回滾,uncheck exception回滾

如果配置了rollbackfor 和 norollbackfor 且兩個都是用同樣的異常,那麼遇到該異常,還是回滾

rollbackfor 和norollbackfor 配置許不會含蓋所有異常,對於遺漏的按照check exception 不回滾,uncheck exception回滾

Spring AOP 宣告式事務

a.程式設計式事務管理 通過transaction template手動管理事務,實際應用中很少使用。b.使用xml配置宣告式事務 實際中用的很多因為 侵入性最小,而且是通過aop實現的。這裡我們講解一下宣告式事務 a.基於 tx 和 aop 命名空間的宣告式事務管理 其與spring aop 結合...

Spring Aop實現宣告式事務

在系統的業務邏輯層中,每個業務會涉及到多個資料庫的操作,業務層其實是通過資料層的多個方法共同完成乙個業務,而這些方法要麼都執行,要麼都不執行,否則會造成資料的不一致,由此我們要對業務層進行事務管理。我們有以下兩種方式實現對業務的事務控制。1.傳統的方式 每個業務方法都手動加上事務控制的 2.採用ao...

宣告式事務

宣告式事務編輯以方法為單位,進行事物控制 丟擲異常,事物回滾。最小的執行單位為方法。決定執行成敗是通過是否丟擲異常來判斷的,丟擲異常即執行失敗 宣告式事務 declarative transaction management 是spring提供的對程式事務管理的方式之一。spring的宣告式事務顧名...