#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();
}
}