Назад к вопросам
Senior
3
Расскажите о паттерне Transactional Outbox — как он работает и зачем используется?
Компании, где спрашивали
ИП Ганус Александр Андреевич
Ответ от нейросети
sobes.tech AI
Паттерн Transactional Outbox используется для обеспечения атомарности между изменениями в базе данных и отправкой сообщений в систему обмена сообщениями (например, Kafka, RabbitMQ). Он решает проблему согласованности данных и сообщений при распределённых транзакциях.
Как работает:
- В рамках одной транзакции базы данных вместе с основной бизнес-операцией записывается запись в специальную таблицу — outbox ("аутбокс"). Эта таблица содержит сообщения, которые нужно отправить во внешнюю систему.
- Отдельный процесс (или сервис) периодически читает новые записи из outbox и отправляет их в систему сообщений.
- После успешной отправки сообщение помечается как отправленное или удаляется из 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
}
Это гарантирует, что сообщение не будет потеряно и не будет отправлено дважды.