Вопрос с собеседования · Spring

При каком исключении @Transactional по умолчанию откатывает транзакцию?

Middle@TransactionalSpring
Ещё спрашивают так:
  • Откатится ли транзакция при checked-исключении?
Коротко

По умолчанию откат — на RuntimeException и Error. На checked-исключения транзакция коммитится. Меняется через rollbackFor и noRollbackFor.

  • @Transactional(rollbackFor = Exception.class) — откат на любое
  • Исключение, пойманное внутри метода, откат не вызывает
  • Если внутренний @Transactional-метод бросил RuntimeException, а внешний поймал — UnexpectedRollbackException при коммите

А ещё Правило унаследовано от EJB: checked — «ожидаемая бизнес-ситуация»

Подробно

Правило по умолчанию: транзакция откатывается, если из метода вылетело непроверяемое исключение (RuntimeException и наследники) или Error. При проверяемом (IOException, свои extends Exception) — коммит. Это часто неожиданно.

Настройка:

  • rollbackFor = {IOException.class} — откат и на эти исключения;
  • noRollbackFor = {BusinessWarning.class} — не откатывать.

Ловушки:

  • поглощённое исключение — try { ... } catch (Exception e) { log } внутри метода: исключение не вылетело — коммит, даже если данные в неконсистентном состоянии;
  • rollback-only — внутренний @Transactional (REQUIRED, та же транзакция) бросил RuntimeException, транзакция помечена «только откат». Внешний метод поймал и продолжил — при коммите Spring бросит UnexpectedRollbackException;
  • ручной откат без исключения — TransactionAspectSupport.currentTransactionStatus().setRollbackOnly().

Многие команды договариваются о бизнес-исключениях как RuntimeException, чтобы правило по умолчанию работало ожидаемо.

Что хотят услышать

  • Правило по умолчанию для unchecked и checked.
  • rollbackFor и noRollbackFor.
  • Поглощённые исключения и rollback-only.

Частые ошибки

  • Ожидать отката при checked-исключении.
  • Ловить исключение внутри транзакционного метода и не пробрасывать.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗При любом исключении, включая checked
  • ✓Только при unchecked (RuntimeException) и Error
  • ✗Только при checked-исключениях
  • ✗Никогда автоматически — нужно вызывать rollback вручную

Что спросят дальше

  • Как настроить rollback на checked?
  • Что делает noRollbackFor?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования