框架采用的是spring管理聲明式事務,這幾天業務開發時遇到了點麻煩,記錄下備忘。
場景:在Service類中使用子事務(saveponit)時,當子事務拋出異常后,此異常處理掉不繼續往外拋,spring在提交主事務時會拋出
org.springframework.transaction.UnexpectedRollbackException: Transaction has been rolled back because it has been marked as rollback
方法調用結構:
假若有A、B、C三個Service類,其實例對象分別為a、b、c,類分別定義如下:
A {
方法() { //propagation="REQUIRED"
try{
b.方法();
} catch (Exception e) {
}
}
}
B{
savePoint方法() { //propagation="NESTED"
c.方法(); //如果這里邊的操作全是普通類(不是Service類)操作,不會有問題。
}
}
C{
方法() { //propagation="REQUIRED"
throw new Exception("出錯");
}
}
通過調試spring源碼
......
Getting transaction for [A.方法] .....
......
Creating nested transaction with name [B.savePoint方法]........
......
Participating in existing transaction
Getting transaction for [C.方法]
........
Participating transaction failed - marking existing transaction as rollback-only
//此時,已把主事務標記成了rollback-only
所以,當在a.方法完成時提交事務時會報Transaction has been rolled back because it has been marked as rollback錯誤。
認真的您可能會發現,在 org.springframework.transaction.support.AbstractPlatformTransactionManager 中有個叫
isGlobalRollbackOnParticipationFailure的參數,默認是true.
源碼中說明:
Switch this to "false" to let the transaction originator make the rollback decision. If a participating transaction fails with an exception, the caller can still decide to continue with a different path within the transaction. However, note that this will only work as long as all participating resources are capable of continuing towards a transaction commit even after a data access failure: This is generally not the case for a Hibernate Session, for example; neither is it for a sequence of JDBC insert/update/delete operations.
大意是:如果isGlobalRollbackOnParticipationFailure為false,則會讓主事務決定回滾,如果當遇到exception加入事務失敗時,調用者能繼續在事務內決定是回滾還是繼續。然而,要注意是那樣做僅僅適用于在數據訪問失敗的情況下且只要所有操作事務能提交。
初步解決方案:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="globalRollbackOnParticipationFailure" value="false" /> <!--指定此參數為false-->
</bean>
經測試,此問題暫時得到解決,不知道會不會引起其它問題,至少目前還沒有發現其它異常。您若通過此方案解決之后出現了新的問題請留信回復,我們一起交流,非常感謝!
posted on 2014-12-20 14:23
fly 閱讀(597)
評論(0) 編輯 收藏 所屬分類:
J2EE