2016-07-11 132 views
0

我正在構建一個工作流系統,其中服務層 - WorkflowServiceImpl處理文檔並向用戶發送通知。 還有另一種服務DocumentServiceImpl,它有一個方法post()方法,它在內部調用WorkflowServiceImpl.process()方法。Spring @Transactional註釋行爲

@Service 
public class WorkflowServiceImpl implements WorkflowService{ 

    @Transactional(propagation=Propagation.REQUIRES_NEW, noRollbackFor=WorkflowException.class) 
    public void process(WorkflowDocument document) throws WorkflowException { 

     Boolean result = process(document); 
     if(!result){ 
      throw new WorkflowException(); 
     } 
    } 

    private Boolean process(WorkflowDocument document){ 
     //some processing on document 
     updateDocument(); 
     sendNotifications(); 
    } 

    private void updateDocument(WorkflowDocument document){ 
     //some update operation 
    } 

    private void sendNotifications(WorkflowDocument document){ 
     //send notifications - insertion operation 
    } 
} 

@Service 
public class DocumentServiceImpl implements DocumentService{ 

    @Autowired private WorkflowService workflowService; 

    @Transactional 
    public void post(){ 

     //some operations 

     workflowService.process(document); 

     //some other operations 
    } 
} 

正如你所看到的,我已經打上

DocumentServiceImpl.post() as @Transactional 
WorkflowServiceImpl.process() as @Transactional(propagation=Propagation.REQUIRES_NEW, noRollbackFor=WorkflowException.class) 

我試圖做到這一點:

1. WorkflowServiceImpl.process() method should commit always(update document and send notifications) - whether a WorkflowException is thrown or not 
2. DocumentServiceImpl.post() method should rollback, when WorkflowException is thrown 

當我嘗試使用上述交易結構

1. When WorkflowException is not thrown, the code worked as expected - committed both WorkflowServiceImpl.process() and DocumentServiceImpl.post() methods 
2. When WorkflowException is thrown, the request processing is not completed (I can see the request processing symbol in the browser) 

我找不到什麼代碼是錯誤的。我使用Spring版本3.1.4

+0

對於'private'方法,'@ Transactional'是無用的,即使你將這些方法設置爲public,它也不起作用,因爲內部方法調用不會通過用於應用AOP的代理。 –

+0

@M。 Deinum我已根據您的建議更正了代碼。你能指導我實現這個目標嗎? – faizi

回答

0

您必須在@Transactional標註爲WorkflowException和傳播一個rollbackForREQUIRES_NEW

@Transactional(rollbackFor = {WorkflowException.class}, propagation = Propagation.REQUIRES_NEW) 
public void post(){ 

    //some operations 

    workflowService.process(document); 

    //some other operations 
} 

這樣會使一個新的事務與DocumentServiceImpl

的POST方法開始
相關問題