考虑下面的代码片段。(我正在使用Spring3.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方法引发的异常,如果没有异常抛出,就发送一封电子邮件。我是在正确的轨道上,还是我们可以改变@事务的行为方式。
发布于 2013-08-28 08:08:31
我通过围绕这个问题进行设计来解决这个问题。发送电子邮件从来就不是交易的一部分。我创建了一个执行事后保存任务的对象。对象将捕获保存终止时抛出的异常,如果没有抛出异常,我将触发一封电子邮件发送出去。您还可以将其放入Spring方面,在成功保存后成功返回时可以执行Spring方面。
经验教训:不要包含不属于标记为@transaction的方法中的步骤。如果它包含在事务中,Spring将默默地处理异常,在事务完成之前不会抛出异常。简而言之,如果一个方法被@注释,那么即使方法中间的一行抛出异常,该方法中的每一行都将被执行。
https://stackoverflow.com/questions/18455934
复制相似问题