Выбор ответа Junior Транзакции и @Transactional спрашивают часто обновлено
Исключение поймано внутри метода
Вопрос
Внутри @Transactional-метода стоит try { repo.save(a); repo.save(b); } catch (Exception e) { log.error("fail", e); }, и второй save упал с RuntimeException на уровне JDBC. Что будет?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Прокси не узнает об ошибке и попытается закоммитить. Прокси видит только исключения, вылетевшие из метода.
Варианты ответа
- Транзакция откатится, потому что было исключение
- Прокси не узнает об ошибке и попытается закоммититьправильный ответ
- Spring повторит метод, раз он завершился с ошибкой
- Транзакция зависнет до истечения таймаута
Разбор
Прокси видит только исключения, вылетевшие из метода. Проглоченное исключение для него означает успех, поэтому будет commit (первый save сохранится). Если ошибка была внутри Hibernate, транзакция могла быть помечена rollback-only, и тогда коммит превратится в UnexpectedRollbackException. В обоих случаях ошибку нужно пробрасывать. Повторов Spring сам не делает.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.