天天看點

Spring事務異常復原,捕獲異常不抛出不會復原

例:  

   類似這樣的方法不會復原 (一個方法出錯,另一個方法不會復原) :  

[html]  view plain  copy  

Spring事務異常復原,捕獲異常不抛出不會復原
Spring事務異常復原,捕獲異常不抛出不會復原
  1. if(userSave){          
  2.     try {         
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);         
  5.      } catch (Exception e) {          
  6.         logger.info("能力開通接口,開戶異常,異常資訊:"+e);         
  7.      }         
  8.  }  

下面的方法復原(一個方法出錯,另一個方法會復原):

[html]  view plain  copy  

Spring事務異常復原,捕獲異常不抛出不會復原
Spring事務異常復原,捕獲異常不抛出不會復原
  1. if(userSave){         
  2.      try {          
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);         
  5.        } catch (Exception e) {         
  6.         logger.info("能力開通接口,開戶異常,異常資訊:"+e);          
  7.         throw new RuntimeException();         
  8.      }          
  9. }  

或者:

[html]  view plain  copy  

Spring事務異常復原,捕獲異常不抛出不會復原
Spring事務異常復原,捕獲異常不抛出不會復原
  1. if(userSave){          
  2.     try {          
  3.         userDao.save(user);          
  4.         userCapabilityQuotaDao.save(capabilityQuota);          
  5.     } catch (Exception e) {          
  6.         logger.info("能力開通接口,開戶異常,異常資訊:"+e);          
  7.         TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();         
  8.     }         
  9.  }  

預設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

繼續閱讀