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

HTTP-вызов внутри транзакции

Вопрос

В @Transactional-методе после UPDATE баланса идёт вызов внешнего платёжного API, который отвечает до 30 секунд. Что здесь плохо?

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

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

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

Коротко

Правильный ответ: Соединение и блокировки держатся весь вызов, а откат не вернёт платёж. Транзакция БД не распространяется на внешний сервис: если после ответа API что-то упадёт и транзакция откатится, деньги уже списаны.

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

  1. Ничего: транзакция защищает и внешний вызов, откатит его при ошибке
  2. Spring запрещает сетевые вызовы внутри транзакции и бросит исключение
  3. Соединение и блокировки держатся весь вызов, а откат не вернёт платёжправильный ответ
  4. Внешний вызов на самом деле выполнится только после коммита

Разбор

Транзакция БД не распространяется на внешний сервис: если после ответа API что-то упадёт и транзакция откатится, деньги уже списаны. А пока ждём ответ, соединение и блокировка строки заняты, и параллельные запросы к тому же счёту встают в очередь. Правильно: короткая транзакция для записи намерения, вызов вне транзакции, затем вторая транзакция с результатом, плюс идемпотентность и outbox или саги.

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

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