Во-первых, я отмечу, что я использую 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..
}
Iстолкнуться с проблемой, когда придет время сделать 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
, но это не сохраняет поведение отката функций.
Я немного растерялся, поэтому буду признателен за любую помощь!