Я перечитал ваш вопрос несколько раз и не уверен, что полностью понял ваш вопрос. Я предполагаю, что вы выполняете someCode , и если это не удается, вы хотели бы выполнить myCustomRollback , в котором есть некоторая информация о someCode. Поэтому я постараюсь дать общий ответ.
Если вы хотите, чтобы весна откатила какой-то код. Он будет выполнять откат только того, что является rollBackAble, например транзакций jdbc. Предположим, у вас есть метод, который выполняет 2 вызова.
@Transactional
public void doStuff(SomeEntity entity, File file) {
persist(entity);
customFileService.createOnFileSystem(file);
throw new RunTimeException();
}
Таким образом, приведенный выше код всегда будет выполнять откат. Это отменит сохранение вашей сущности, но не создание вашего файла, поскольку он не управляется транзакциями Spring, если только вы не предоставите для него собственную реализацию.
Во-вторых, Spring предоставляет 2 способа работы с транзакциями:
- Spring AOP: во время выполнения создается прокси , который украсит ваш код транзакционными данными. Если ваш класс будет называться MyClass, то Spring создаст имена классов MyClassProxy, которые обернут ваш код в код транзакции.
- AspectJ: во время компиляции ваш файл .class будет скорректирован, а код транзакции будет встроен в ваш метод.
Подход аспектаJ кажется сложнее настроить, но он не так уж и прост и его использование намного проще. Поскольку все, что помечено @Transactional, будет встроено (сплетено) с кодом. Для Spring AOP это не так. Например, транзакционные внутренние вызовы методов в Spring будут игнорироваться! Таким образом, aspectJ обеспечивает более интуитивный подход.
Вернуться к тому, что я думаю, ваш вопрос (код всего в 1 классе):
public void doSomeCode() {
Object restCall = initialize();
try {
execute(restCall);
} catch (CustomException e) {
myCustomRollback(restCall; e);
}
}
@Transactional(rollbackFor = CustomException.class)
private void execute(Object restCall) throws CustomException {
// jdbc calls..
restCall = callRest(restCall);
throw new CustomException();
}
void myCustomRollback(Object restCall, CustomException e) {
...
}
Приведенный выше код будет работать только с AspectJ! Так как вы делаете внутренние вызовы методов, которые также кажутся приватными! АОП во время выполнения не может справиться с этим.
Итак, все, что происходит (в режиме rollbackAble) при выполнении, будет откатано. А в doStuff у вас есть информация об объектах, которые использовались в execute, теперь вы можете использовать в myCustomRollback для отката ваших REST-компонентов вручную.
Не уверен, правильно ли я ответил на этот вопрос, но надеюсь, что это поможет кому-то с подобной проблемой.