Spring Boot - Hibernate, откат успешно сохранен при исключении - PullRequest
0 голосов
/ 18 сентября 2019

Я создаю приложение с помощью 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?Как сделать, чтобы оба сохранения работали как одна транзакция, и откатить обе, при ошибке, возникшей в результате сохранения?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2019

Hello @Transactional не работает с закрытым или защищенным методом, ваш метод должен быть открытым.Почему?Потому что Spring должен создать прокси для разграничения транзакций и поведения.Поскольку нет возможности прокси защищенного или частного метода, ваша аннотация просто игнорируется.

0 голосов
/ 19 сентября 2019

вам просто нужно аннотировать с помощью @Transactional метод сервиса, который вызывается в контроллере, а не этот метод.Или вы можете аннотировать класс Service с помощью @ Transactional

...