Событие в брокер после коммита: почему теряются доменные события
Сервис заказов работает так:
await prisma.$transaction(async (tx) => {
await tx.order.create({ data: order });
await tx.orderItem.createMany({ data: items });
});
await kafka.send({ topic: 'order.created', messages: [{ value: JSON.stringify(order) }] });
Раз в несколько дней склад не получает заказ, который в базе есть; изредка бывает и обратное — событие ушло, а заказа нет. Как устроена проблема и чем её решают?
- Достаточно перенести отправку внутрь транзакции: при ошибке отправки транзакция откатится и рассинхронизации не будет
- Это двойная запись в два независимых хранилища; лечится паттерном Transactional Outbox
- Проблема в надёжности брокера: нужно включить подтверждение записи от всех реплик и увеличить число повторов продюсера
- Нужно отправлять событие до транзакции: потребитель гарантированно узнает о заказе, а запись в базу уже не подведёт
