Выбор ответа Senior Транзакции и @Transactional обновлено

Отправить письмо после коммита

Вопрос

Как отправить письмо о заказе только если транзакция создания заказа успешно закоммитилась?

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

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

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

Коротко

Правильный ответ: @TransactionalEventListener(phase = AFTERCOMMIT). Последняя строка метода выполняется до коммита: коммит ещё может упасть (constraint, сериализация), а письмо уже ушло. finally отправит даже при ошибке.

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

  1. @TransactionalEventListener(phase = AFTER_COMMIT)правильный ответ
  2. Отправить письмо последней строкой @Transactional-метода
  3. Отправить письмо в блоке finally после сохранения заказа
  4. Отправка в методе с @Transactional(propagation = REQUIRES_NEW)

Разбор

Последняя строка метода выполняется до коммита: коммит ещё может упасть (constraint, сериализация), а письмо уже ушло. finally отправит даже при ошибке. REQUIRES_NEW не связан с исходом внешней транзакции. TransactionalEventListener вызывает обработчик после успешного коммита. Для гарантированной доставки (например, в Kafka) используют transactional outbox.

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

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