NOTE

2.8 Transactional Outbox / Local Message Table

How to commit business state and an outgoing event in one local database transaction, then asynchronously publish with retries and idempotent consumption.

Distributed SystemsUpdated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. The Dual-Write Problem

Suppose service A creates an order and must tell service B to grant points. These two operations cannot safely be implemented as:

  1. commit the order;
  2. publish a message once.

If the process crashes between the two, the order exists but the event is lost.

2. Transactional Outbox Pattern

Service A uses one local transaction:

BEGIN;
-- write business state
-- insert outgoing event into outbox table
COMMIT;

A separate publisher scans or streams committed outbox rows and sends them to the message broker. Successfully published rows are marked or removed according to the implementation.

Service B consumes the event and applies its own local transaction. Because delivery may repeat, B must make processing idempotent, for example with a processed-message key or a naturally idempotent state transition.

3. Properties

  • avoids the producer-side database/MQ dual-write gap;
  • decouples downstream processing from the producer transaction;
  • normally gives at-least-once publication/consumption semantics;
  • requires cleanup, retry policy, lag monitoring, and poison-message handling.

Change-data-capture can replace explicit polling while preserving the same core idea: the outgoing event is committed atomically with the business data.

Loading helpful count