例:
類似這樣的方法不會復原 (一個方法出錯,另一個方法不會復原) :
[html] view plain copy
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力開通接口,開戶異常,異常資訊:"+e);
- }
- }
下面的方法復原(一個方法出錯,另一個方法會復原):
[html] view plain copy
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力開通接口,開戶異常,異常資訊:"+e);
- throw new RuntimeException();
- }
- }
或者:
[html] view plain copy
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力開通接口,開戶異常,異常資訊:"+e);
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- }
- }
預設Spring 事務隻在發生未被捕獲的 RuntimeExcetpion時才復原。
Spring Aop 異常捕獲原理:被攔截的方法需顯式抛出異常,并不能經任何處理,這樣Aop代理才能捕獲到方法的異常,才能進行復原,預設情況下Aop隻捕獲RuntimeExcetpion的異常,但可以通過 配置來捕獲特定的異常并復原換句話說在service的方法中不使用try catch 或者在catch中最後加上throw new RuntimeExcetpion(),這樣程式異常時才能被Aop捕獲進而復原
解決方案:
方案1.例如service層處理事務,那麼service中的方法中不做異常捕獲,或者在catch語句中最後增加throw new RuntimeExcetpion()語句,以便讓Aop捕獲異常再去復原,并且在service上層(webservice用戶端,view層action)要繼續捕獲這個異常并處理
方案2.在service層方法的catch語句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();語句,手動復原,這樣上層就無需去處理異常(現在項目的做法)。
原文連結:https://blog.csdn.net/qq724581322/article/details/51427100
二。
//zh已測試通過
@Transactional(rollbackFor=Exception.class)
public void methodName() {
// 會復原
throw new Exception("...");
// 會復原
throw new RuntimeException("...");
}
rollbackFor 預設就是 RuntimeException
@Transactional(rollbackFor=RuntimeException.class) 或者是 @Transactional()
public ItimDaoImpl getItemDaoImpl() {
// 不會復原
throw new Exception("...");
// 會復原
throw new RuntimeException("");
}
原文連結:https://blog.csdn.net/zh521zh/article/details/52687922