Вложенная транзакция для атомарности (Propogation.REQUIRED_NEW / Propogation.NESTED) - PullRequest
1 голос
/ 27 января 2012

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

Я немного растерялся, поэтому буду признателен за любую помощь!

1 Ответ

0 голосов
/ 30 января 2012

Не думаю, что в этом случае вы сможете использовать свою аннотированную функцию deactivateUnit. Возможно, вам придется попробовать использовать функцию-обертку с REQUIRES_NEW, вызывая вспомогательную функцию, которая не аннотирована. Затем вы бы также вызвали вспомогательную функцию в вашем реактиве метода activtivateUnit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...