首先,我会注意到我正在使用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
和deactivateUnit
函数的原子activateUnit
任务,如果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
,但这不会保留函数的回滚行为。
我有点失落,所以我很感激任何帮助!
答案 0 :(得分:0)
在这种情况下,我认为您无法使用最初注释的deactivateUnit函数。您可能必须尝试使用包装函数,REQUIRES_NEW调用一个未注释的辅助函数。然后,您还可以在您的reactivateUnit方法中调用辅助函数。