Я создаю приложение с помощью Spring Boot v2.1.3.RELEASE и Hibernate v5.3.6.
Ранее я задавал вопрос о том, как выполнить откат с @Transactional для нескольких служб / репозиториев.Я получил то, что мне было нужно, связав мои сущности с аннотациями @OneToOne и @OneToMany.
Теперь я столкнулся с новой проблемой.Внутри функции в одном сервисе я сохраняю два отдельных списка сущностей.Один список сохраняется, а другой - не удается из-за нарушения ограничения уникального ключа.Ожидается, что это не удастся, так как я тестирую.
Но я не выяснил, как аннотировать мой Сервис или метод с помощью @Transactional, так что, когда второй список не удается сохранить, он также откатит любой успешныйсохраняет первый список.
Например:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
protected void saveLists() {
List<Object> list1 = this.repository.getListOne();
List<Object> list2 = this.repository.getListTwo();
//Loop through list one and do some manipulation
//Loop through list two and do some manipulation
this.repository.saveAll(list1); // this saves all successfully
this.repository.saveAll(list2); // this has unique key exception
// rollback both list1 and list2 changes
}
В приведенном выше примере данные из списка list1 успешно сохраняются и появляются в базе данных после создания исключения из списка list2.
Я подумал, что, поскольку они находятся в одной и той же службе и используют один и тот же метод, используя один и тот же репозиторий, они будут использовать одну и ту же транзакцию, и что Hibernate не будет фиксировать транзакцию, пока не покинет этот метод безошибки.
Но, похоже, это не так.Поскольку данные для списка один становятся подтвержденными и не откатываются.
Что-то мне не хватает в аннотации @Transactional?Как сделать, чтобы оба сохранения работали как одна транзакция, и откатить обе, при ошибке, возникшей в результате сохранения?