> Была ли важна атомарность изменений в хранилище и отправки сообщений (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: BetBoom
Стек: Go
> Пример ответа
Да, атомарность изменений в хранилище и отправки сообщений критически важна для обеспечения консистентности данных в распределённых системах. Без неё возможны ситуации, когда данные записаны, но сообщение не отправлено (или наоборот), что приводит к рассинхронизации между сервисами. В Go для этого применяются несколько подходов:
-
Transactional Outbox - запись события в ту же БД, что и бизнес-данные, в рамках одной транзакции. Отдельный процесс (например, фоновая горутина) читает outbox и отправляет сообщения, гарантируя at-least-once delivery.
-
Двухфазный коммит (2PC) - координация между хранилищем и брокером, но это добавляет сложность и снижает производительность.
-
Идемпотентность обработчиков - если сообщение всё же будет отправлено повторно, получатель должен безопасно его обработать.
Пример реализации outbox на Go:
GOtype Order struct {ID stringItems []string}type OutboxMessage struct {ID stringTopic stringPayload []byteCreatedAt time.Time}func CreateOrder(ctx context.Context, db *sql.DB, producer *kafka.Producer, order Order) error {tx, err := db.BeginTx(ctx, nil)if err != nil {return err}defer tx.Rollback()// 1. Сохраняем заказif _, err := tx.ExecContext(ctx, "INSERT INTO orders (id, items) VALUES ($1, $2)", order.ID, order.Items); err != nil {return err}// 2. Сохраняем сообщение в outboxmsg := OutboxMessage{ID: uuid.New().String(),Topic: "order_created",Payload: mustMarshal(order),}if _, err := tx.ExecContext(ctx, "INSERT INTO outbox (id, topic, payload, created_at) VALUES ($1, $2, $3, $4)",msg.ID, msg.Topic, msg.Payload, time.Now()); err != nil {return err}// 3. Коммитим транзакциюif err := tx.Commit(); err != nil {return err}// 4. Отправляем сообщение (уже после коммита)// В случае ошибки - повторит фоновый процессreturn producer.SendMessage(ctx, msg.Topic, msg.Payload)}
Фоновый процесс (например, запущенный в отдельной горутине) периодически проверяет outbox и повторно отправляет неотправленные сообщения, обеспечивая атомарность в конечном счёте.
> Похожие задачи по backend
Какие паттерны микросервисов использовались, например саги, apigateway
Использовали ли транзакции при отправке сообщений в брокер
Как устроен процесс карьерного роста, пересмотра зарплаты и грейдов
Кто ставит задачи и как они распределяются
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью