Выбор ответа Junior Транзакции и @Transactional спрашивают часто обновлено

Исключение поймано внутри метода

Вопрос

Внутри @Transactional-метода стоит try { repo.save(a); repo.save(b); } catch (Exception e) { log.error("fail", e); }, и второй save упал с RuntimeException на уровне JDBC. Что будет?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Прокси не узнает об ошибке и попытается закоммитить. Прокси видит только исключения, вылетевшие из метода.

Варианты ответа

  1. Транзакция откатится, потому что было исключение
  2. Прокси не узнает об ошибке и попытается закоммититьправильный ответ
  3. Spring повторит метод, раз он завершился с ошибкой
  4. Транзакция зависнет до истечения таймаута

Разбор

Прокси видит только исключения, вылетевшие из метода. Проглоченное исключение для него означает успех, поэтому будет commit (первый save сохранится). Если ошибка была внутри Hibernate, транзакция могла быть помечена rollback-only, и тогда коммит превратится в UnexpectedRollbackException. В обоих случаях ошибку нужно пробрасывать. Повторов Spring сам не делает.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.