Sobes.tech
Back to questions
Senior
4

Расскажите о паттерне Transactional Outbox — как он работает и зачем используется?

Companies where asked
ИП Ганус Александр Андреевич

Answer from AI

sobes.tech AI

Паттерн Transactional Outbox используется для обеспечения атомарности между изменениями в базе данных и отправкой сообщений в систему обмена сообщениями (например, Kafka, RabbitMQ). Он решает проблему согласованности данных и сообщений при распределённых транзакциях.

Как работает:

  1. В рамках одной транзакции базы данных вместе с основной бизнес-операцией записывается запись в специальную таблицу — outbox ("аутбокс"). Эта таблица содержит сообщения, которые нужно отправить во внешнюю систему.
  2. Отдельный процесс (или сервис) периодически читает новые записи из outbox и отправляет их в систему сообщений.
  3. После успешной отправки сообщение помечается как отправленное или удаляется из outbox.

Таким образом, изменения в базе и запись о событии происходят атомарно, а отправка сообщений происходит асинхронно, что повышает надёжность и упрощает обработку ошибок.

Пример на Go (упрощённо):

// В рамках транзакции
tx, _ := db.Begin()
// Обновляем бизнес-данные
_, _ = tx.Exec("UPDATE orders SET status = ? WHERE id = ?", "paid", orderID)
// Добавляем запись в outbox
_, _ = tx.Exec("INSERT INTO outbox (event_type, payload) VALUES (?, ?)", "OrderPaid", payload)
tx.Commit()

// Отдельный воркер читает из outbox и отправляет сообщения
rows, _ := db.Query("SELECT id, event_type, payload FROM outbox WHERE sent = false")
for rows.Next() {
    // Отправка в Kafka или другую систему
    // После успешной отправки обновляем статус sent = true
}

Это гарантирует, что сообщение не будет потеряно и не будет отправлено дважды.