Comments 8
Как то неполно раскрыт аспект outbox паттерна. Одно из основных применений его это не просто единичная запись в аутбокс, так как и запись в аутбокс может выпасть с ошибкой. Например можно объединить запись о новом пользователе в транзакцию с записью в аутбокс, в этом случае на уровне бд булет гарантировано, что есои пользователь успешно записался, то и аутбокс тоже, то есть либо всё, либо ничего. Плюс нужен надежный месседж брокер с такими же гарантиями, некоторые лепят альтернативы кафок сами. Вот в этом случае аутбокс как раз надёжен. В вашем примере можно обойтись и записью напрямую в брокер, с таким же успехом как и в бд.
Да, можно сделать так, чтобы писалось сразу в брокер... но нужно ли?
- Проблема с тем, что будут двойные записи\не полные записи (в случае отказа записи в БД или брокер) - ситуации, когда данные есть в БД но их нет в брокере или в другой конфигурации когда данные есть в брокере но нет в БД.
Если взглянете на схему в статье и описание к ней - то обратите внимание, что запись юзера и запись в Outbox проходит в одной транзакции, и в примере с методом RegisterUserAsync это наглядно показано.
Плюс, Outbox делает так, что сообщение будет гарантированно доставлено хотя бы один раз.
Ну, условная транзакция и происходит, тк используется UnitOfWork.
Если база данных не доступна, то как мы запишем в outbox? Тогда придётся ещё одну БД заводить и это не попахивает снижением точек отказа..
Получается, что этот паттерн можно использовать только в stateful сервисах.
интересна реализация background worker, потому что если приложение масштабировано, то может произойти такая ситуация, когда несколько воркеров с разных нод одновременно считали из outbox хранилища письмо и оба попытаются его отправить
Паттерн Outbox для надежного обмена сообщениями в микросервисах