Transactional Outbox для финансовых операций¶
Раздел 05 · Редакционный стандарт
Тип материала — референсная архитектура. HYPOTHETICAL — схемы и операции. INFERENCE — инженерные рекомендации и критерии выбора. Внешние контракты ограничены источниками ниже.
Бизнес-задача¶
Довести факт committed posting до downstream при сбоях relay.
Требования¶
Хранить backlog до доказанного покрытия. Отделить событие и команду. Поддержать исторический replay.
Поток данных и владение состоянием¶
flowchart LR
A["Posting API"] --> B["Ledger DB transaction"]
B --> C["Outbox table"]
C --> D["Relay and Kafka"]
D --> E["Consumer inbox"]
Ledger владеет фактом. Outbox хранит намерение публикации.
Транзакционные границы¶
Journal и outbox row фиксируются вместе. Kafka ACK и relay marker отделены. Inbox и effect фиксируются вместе в target.
Порядок и идемпотентность¶
Stable event ID и aggregate revision. Consumer проверяет gaps, если delta зависит от предшественника.
Нормальная последовательность¶
sequenceDiagram
participant A as Posting API
participant B as Ledger DB transaction
participant C as Outbox table
participant D as Relay and Kafka
A->>B: Submit journal and publish intent
B->>C: Insert outbox row in ledger transaction
C-->>B: Return committed journal and event ID
B->>D: Publish durable event to broker
Отказ и восстановление¶
sequenceDiagram
participant B as Ledger DB transaction
participant C as Outbox table
participant E as Recovery operator
B->>C: Broker ACK is lost before relay marker
Note over B,C: Outcome becomes uncertain
E->>C: Recover retained outbox row and resend same event ID
E->>B: Resume from verified boundary
Сбой после broker ACK до marker создаёт повтор. При потере WAL slot восстановить покрытие через сохранённый outbox.
Сверка¶
Сопоставить journal IDs, outbox IDs и consumer dispositions по cut.
Граница очистки. Outbox identity включается в record key или header и сохраняется при каждой попытке. Публикующий worker хранит lease или claim для ограничения параллельных повторов. Истечение lease допускает повтор и потому не заменяет dedup. После отправки сверка проверяет event ID по consumer disposition. Compaction или удаление journal events требует явного покрытия archive и согласованного срока replay.
Наблюдаемость¶
Oldest backlog, WAL pressure и duplicate rate.
Безопасность и применимость требований¶
Минимизировать payload и ограничить ACL.
Альтернативы и trade-offs¶
Polling уменьшает зависимость от WAL. CDC снижает polling I/O.
Вопросы на собеседовании¶
Зачем ждать ACK перед marker? Иначе crash между marker и send оставит потерю.