2016-07-11 2 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) 

Я не могу найти, что неправильно с кодом. Я использую весеннюю версию 3.1.4

+0

«@ Transactional' на' private' методы бесполезны, даже если вы сделаете эти методы «общедоступными», это не будет работать, поскольку вызовы внутренних методов не проходят через прокси-сервер, который используется для применения АОП. –

+0

@M. Deinum Я скорректировал код согласно вашему предложению. Можете ли вы, пожалуйста, направить меня, чтобы добиться этого. – faizi

ответ

0

Вы должны иметь в @Transactional аннотации для WorkflowException и распространения в rollbackFor в REQUIRES_NEW

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

    //some operations 

    workflowService.process(document); 

    //some other operations 
} 

Это позволит сделать новую транзакцию быть запущен с постом методом DocumentServiceImpl

Смежные вопросы