1

首先,我会注意到我使用 Spring + Hibernate 作为我的 JPA2 实现。我的应用程序配置了 JpaTransactionManager 和 HibernateJpaDialect。

我有一个停用一个单元的功能,我有一个包装停用多个单元的功能。单元停用工作调用外部服务,如果该调用超时或返回错误状态,它将抛出异常。如果单个单元停用失败(通过此外部服务调用或由于 RuntimeException),我只想回滚该单元的事务。

我可以使用 Propogation.REQUIRES_NEW 来实现这一点,基本上如下:

@Transactional
public void deactivateUnits(List<String> names){
    for(String name : names){
        deactivateUnit(name);
    }
}
@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void deactivateUnit(String name) throws MyException{
    ..snip..
    //Some code that throws MyExceptions or RuntimeExceptions
    ..snip..
}

这非常有效。

这种风格也很好地扩展到激活。

@Transactional
public void activateUnits(List<String> names){
    for(String name : names){
        activateUnit(name);
    }
}
@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void activateUnit(String name) throws MyException{
    ..snip..
    //Some code that throws MyExceptions or RuntimeExceptions
    ..snip..
}

然而,当我需要做的时候,我遇到了一个问题reactivation。我想要的是一个reactivation利用现有deactivateUnitactivateUnit函数的原子任务,这样如果或者deactivateUnit或者activateUnit导致回滚,则整个函数将回滚。

我对此的天真尝试不起作用:

@Transactional(propogation=Propogation.REQUIRES_NEW, rollbackFor=MyException.class)
public void reactivateUnit(String newName, String oldName) throws MyException{
    deactivateUnit(oldName);
    activateUnit(newName);
}

如果activateUnit回滚,deactivateUnit则不会。

我想也许我应该将激活和停用的传播更改为NESTED,但这并不能保留函数的回滚行为。

我有点茫然,所以我很感激任何帮助!

4

1 回答 1

0

在这种情况下,我认为您将无法使用您最初注释的 deactivateUnit 函数。您可能必须尝试使用​​带有 REQUIRES_NEW 的包装函数调用未注释的辅助函数。然后,您还将在 reactivateUnit 方法中调用辅助函数。

于 2012-01-30T15:21:19.253 回答