2016-07-11 29 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方法开始
相关问题