Я использую Spring и Hibernate в одном из приложений, над которым я работаю, и у меня возникла проблема с обработкой транзакций.
У меня есть класс обслуживания, который загружает некоторые объекты из базы данных, изменяет некоторые из их значений, а затем (когда все действительно) совершает эти изменения в базе данных. Если новые значения недействительны (которые я могу проверить только после их установки), я не хочу сохранять изменения. Чтобы предотвратить Spring/Hibernate от сохранения изменений, я вызываю исключение в методе. Это приводит к следующей ошибке:
Could not commit JPA transaction: Transaction marked as rollbackOnly
И это сервис:
@Service
class MyService {
@Transactional(rollbackFor = MyCustomException.class)
public void doSth() throws MyCustomException {
//load entities from database
//modify some of their values
//check if they are valid
if(invalid) { //if they arent valid, throw an exception
throw new MyCustomException();
}
}
}
И вот как я его вызываю:
class ServiceUser {
@Autowired
private MyService myService;
public void method() {
try {
myService.doSth();
} catch (MyCustomException e) {
// ...
}
}
}
То, что я ожидал бы: Никаких изменений в базе данных и никаких исключений, видимых для пользователя.
Что происходит: никаких изменений в базе данных, но приложение сбой:
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction;
nested exception is javax.persistence.RollbackException: Transaction marked as rollbackOnly
Он правильно устанавливает транзакцию на rollbackOnly, но почему сбой отката с исключением?