【发布时间】:2012-01-26 22:23:37
【问题描述】:
首先,我会注意到我使用 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,但这并不能保留函数的回滚行为。
我有点茫然,所以我很感激任何帮助!
【问题讨论】:
标签: hibernate spring transactions jpa-2.0 spring-transactions