Откат не работает для Springboot JpaRepository

#spring-boot #hibernate #spring-data-jpa

Вопрос:

У меня есть приложение Spring Boot (v2.4.1) с гибернацией и JpaRepository, как Dao. Вот код:

 import javax.transaction.Transactional;

    @Service
    public class SomeService {
    
        public void executeJob(){
         executeJob(1L);
        }
        @Transactional
        public void executeJob(Long carId){
            Car car = carDao.findById(carId);
            car.setStatus("Destroyed");
            carDao.save(car);
            throw new Exception();
        }
    
    }
 

Итак, после создания исключения я ожидаю, что транзакция будет откатана, и car не будет обновляться в базе данных.
Но это не так.

Я заглянул в журналы и обнаружил, что JpaTransactionManager открывает и фиксирует транзакцию два раза. Первый раз для carDao.findById(carId). Второй раз для carDao.сохранить(автомобиль).

И это, похоже, является причиной отсутствия отката транзакции.

Я полагаю, что это может быть связано с механизмом спящего режима. Но spring.jpa.properties.org.впадает в спячку.FlushMode=НИКОГДА тоже не работает…

Есть какие-нибудь идеи? Спасибо.

Ответ №1:

Транзакция не была откатана, потому что Spring по умолчанию не выполняет откат при возникновении проверенных исключений.

Итак, у вас есть два варианта:

1 — Измените свое исключение на непроверенное исключение (расширяет исключение RuntimeException)

2 — Заставляет Spring откатить проверенное исключение.

Если вы выберете второй вариант, ваш код будет выглядеть следующим образом:

 import org.springframework.transaction.annotation.Transactional;

@Service
public class SomeService {

    @Transactional(rollbackFor = Exception.class)
    public void executeJob() {
        executeJob(1L);
    }

    @Transactional(rollbackFor = Exception.class)
    public void executeJob(Long carId) {
        Car car = carDao.findById(carId);
        car.setStatus("Destroyed");
        carDao.save(car);
        throw new Exception();
    }

}