2017-09-15 96 views
1

我在我的應用程序的服務電話,使遠程網絡調用其他服務,以及DB調用。春季啓動對回滾壞交易與@Transactional良好的支持,但我想知道如果我可以定義使用註釋定製的回退過程。回滾註釋在Java中

我需要回滾對其他服務的數據以及數據庫。

在代碼中,我能做到這一點是這樣的:

@Transactional 
public void doSomethingComplicated() { 
    try { 
     srvcOne.makeRemoteNetworkCall(); 
     srvcTwo.makeDatabaseCall(); 
    } catch(Exception e) { 
     srvcOne.rollBackNetworkCall(); 
    } 
} 

,但我希望我可以做這樣的事情:

@Transactional 
@MyCustomRollbackListener(handler = MyCustomRollBackHandler.class) 
public void doSomethingComplicated() { 
    srvcOne.makeRemoteNetworkCall(); 
    srvcTwo.makeDatabaseCall(); 
} 

並在處理程序:

public class MyCustomRollBackHandler { 

    public void handleRollback() { 
     srvcOne.rollBackNetworkCall(); 
    } 

} 

我實現了一個全局異常監聽器,我能夠得到異常來自的類,但我沒有辦法得到實現方法具d並檢索其上的任何註釋。這是我最初的嘗試:

@ControllerAdvice 
public class RollbackExceptionListener{ 

    private static final Logger logger = LoggerFactory.getLogger(RollbackExceptionListener.class); 

    @ExceptionHandler(Exception.class) 
    public void lookForAnnotationClassForException(final Exception exception) { 
     logger.error("Exception thrown", exception); 

     final StackTraceElement topElement = exception.getStackTrace()[0]; 
     final Class callingClass = topElement.getClass(); 
     final String methodName = topElement.getMethodName(); 


     try { 
      // Can't get the method with just the name, need to 
      // know the params as well. 
      final Method method = callingClass.getMethod(methodName); 
      // Retrieve the annotation on the method and call the handler 
     } catch (NoSuchMethodException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

有沒有辦法做這樣的事情?

回答

1

參數不是Stacktrace的一部分。如果該方法是唯一的,即不超載,則可以使用getMethods()來找到它?想到其他的東西,也許你可以看看Aspects在執行之前將該方法包裝在某個處理程序中。可以在編譯時或運行時完成。

方面本身可以進行回滾,它可以用你需要的信息豐富異常,或者可以在重新拋出異常之前用方法中定義的處理程序類設置一些ThreadLocal變量。然後,您可以在發現異常的地方從ThreadLocal中獲取該值。