Spring @Transaction注释和异常处理

时间:2013-08-27 02:19:06

标签: java spring exception-handling spring-transactions

请考虑以下代码段。 (我使用的是Spring 3.1和Hibernate 3.6)

@Override
@Transactional
public <T extends Termination> void progressToPendingStage(Class<T> entity,
        Long terminationId, String userName) throws Exception {

    Termination termination = findTerminationById(entity, terminationId);
    //TODO improvise such that email does not get sent if data is not saved
    if (termination.getStatus().equals(TerminationStatus.BEING_PREPARED.toString())) {
        termination.setStatus(TerminationStatus.PENDING.toString());
        termination.setSubmittedDate(new Date());
        termination.setSubmittedBy(userName);
        saveOrUpdateTermination(termination);
        //Send an email to SAS
        emailHelper.configureEmailAndSend(termination);
    }   

}

上述方法的单元测试表明,无论saveOrUpdateTermination(终止)是否抛出异常,都将发送电子邮件。在进一步测试和一些研究中,我发现这种行为是预期的行为。这不是业务规则所要求的。只有在终止记录成功保存后才能发送电子邮件。有关如何使其以所需方式运行的任何建议?我能想到的一种方法是让调用者处理progressToPendingStage方法抛出的异常,如果没有抛出异常,则发送一封电子邮件。我是在正确的轨道上还是可以改变@Transaction的行为方式。

1 个答案:

答案 0 :(得分:0)

我通过围绕问题进行设计解决了这个问题。发送电子邮件从未打算成为交易的一部分。我创建了一个执行保存后任务的对象。该对象将捕获保存终止时抛出的异常,如果没有抛出异常,则会触发发送的电子邮件。人们也可以把它放在一个Spring方面,它可以在成功保存后成功返回时执行。

课程学习:不要包含不属于标有@transaction的方法的步骤。如果它包含在一个事务中,Spring将默默处理异常并且不会抛出异常直到事务完成。 简而言之,如果使用@Transaction注释方法,即使方法中间的一行引发异常,该方法中的每一行都将执行。