2016-07-11 9 views
0

Ich bin ein Workflow-System, wo eine Service-Schicht - WorkflowServiceImpl, ein Dokument verarbeiten und Benachrichtigungen an Benutzer senden. Es gibt einen anderen Dienst DocumentServiceImpl, der eine Methode post() Methode hat, die intern WorkflowServiceImpl.process()-Methode aufruft.Spring @Transactional Annotation Verhalten

@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 
    } 
} 

Wie Sie sehen können, habe ich

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

Ich versuche, dies zu erreichen:

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 

Als ich versuchte, die oben genannten Transaktion Konfigurationen mit

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) 

Ich kann was nicht finden stimmt nicht mit dem Code überein. Ich bin mit Feder Version 3.1.4

+0

Die '@ Transactional' auf' private' Methoden sind nutzlos, selbst wenn Sie diese Methoden 'public' machen würden, würde es nicht funktionieren, da interne Methodenaufrufe nicht den Proxy passieren, der zum Anwenden von AOP verwendet wird. –

+0

@M. Deinum habe ich den Code nach deinem Vorschlag korrigiert. Können Sie mir bitte helfen, den Fall zu erreichen? – faizi

Antwort

0

Sie benötigen ein rollbackFor im @Transactional Anmerkung haben für WorkflowException und Fortpflanzung als REQUIRES_NEW

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

    //some operations 

    workflowService.process(document); 

    //some other operations 
} 

Dies wird eine neue Transaktion macht mit post-Methode von DocumentServiceImpl gestartet werden

Verwandte Themen