⚡ Outbox-паттерн: спасение от потерянных событий (и денег)

⚡ Outbox-паттерн: спасение от потерянных событий (и денег)

В одном из первых постов я рассказывал, как из-за моей ошибки контора потеряла 10к $. Тогда я отправлял события в очередь до записи в БД. Запрос к БД упал, а уведомление уже улетело в платежный сервис. В итоге деньги списали, но не зафиксировали в системе, а потом это повторилось еще много-много раз.

Если бы тогда использовали реляционную БД и Outbox-паттерн, этого бы не случилось.

🤔 В чем проблема?

Типичная схема взаимодействия с брокером:

1 Пишем данные в БД

2 Отправляем событие в очередь

Но что если брокер упал или вызов события не прошел после успешного коммита в БД? Система потеряет важное уведомление, а другой сервис никогда не узнает об изменениях.

Решения без Outbox:

🔹 Повторять отправку? — Дубликаты и сложность в обработке

🔹 Держать транзакцию до подтверждения от брокера? — Тормоза в БД

🔹 Игнорировать? — Потерянные данные и баги

🛠 Как решает Outbox?

Вместо того чтобы сразу пушить событие:

✅ Записываем его в специальную таблицу (outbox) в той же транзакции, что и изменение данных

✅ Отдельный процесс (consumer, cron-job, Debezium) читает outbox и отправляет события в брокер

✅ После успешной отправки удаляем запись из outbox

🎯 Почему это круто?

✔ Гарантия доставки — без потерь, даже если брокер лег

✔ Идемпотентность — события можно повторно обработать без дубликатов

✔ Разделение ответственности — бизнес-логика в одном месте, отправка в другом

🚀 Когда использовать?

✔ Если твои сервисы взаимодействуют через event-driven архитектуру

✔ Если тебе нужно гарантированно отправлять события, даже при сбоях

✔ Если ты используешь реляционную БД и хочешь избавиться от сложностей с distributed transactions

Если бы у нас тогда был Outbox + реляционная БД, я бы просто записал событие в outbox в одной транзакции с изменением данных. Даже если бы платежный сервис упал, событие никуда бы не пропало — оно бы отправилось при следующей обработке.

Вывод: если работаешь с реляционной БД и событиями — Outbox обязателен. Уже используешь или пока надеешься на удачу? Давай обсудим в комментах! 💬

Начать дискуссию