Spring @Transactional注释行为

时间:2016-07-11 07:51:51

标签: java spring spring-mvc spring-transactions

我正在构建一个工作流系统,其中一个服务层 - WorkflowServiceImpl,处理文档并向用户发送通知。 还有另一项服务DocumentServiceImpl,它有一个方法post()方法,内部调用WorkflowServiceImpl.process()方法。

@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版本。

1 个答案:

答案 0 :(得分:0)

您需要在rollbackFor注释中添加@Transactional WorkflowException并将传播标记为REQUIRES_NEW

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

    //some operations

    workflowService.process(document);

    //some other operations
}

这将使用DocumentServiceImpl的post方法启动新事务