The article discusses implementing the Outbox pattern in Go and PostgreSQL for resilient system design. It addresses issues like failed message broker calls or crashes causing inconsistent states by ensuring database operations and message publishing are atomic. The solution involves saving messages to an outbox table within the same transaction as business data changes, using a background process called Message Dispatcher to handle delivery. By Alex Pliutau.

An example schema for an outbox table might look like this:

CREATE TABLE outbox (
    id uuid PRIMARY KEY,
    topic varchar(255) NOT NULL,
    message jsonb NOT NULL,
    state varchar(50) NOT NULL DEFAULT 'pending', -- e.g., pending, processed
    created_at timestamptz NOT NULL DEFAULT now(),
    processed_at timestamptz
);

Also article mentions:

  • The Outbox pattern ensures atomicity between database updates and message publishing using a dedicated table.
  • It prevents inconsistent states by storing messages within the same transaction as business data changes.
  • A Message Dispatcher (Relay) processes messages from this outbox table, handling delivery with retries if needed.
  • PostgreSQL’s Write-Ahead Log can enable real-time message streaming via logical replication for lower latency.
  • Idempotency must be designed into consumers to handle duplicate messages reliably.

To summarize, the Outbox Pattern ensures that a message was sent (e.g. to a queue) successfully at least once. With this pattern, instead of directly publishing a message to the queue, we store it in temporary outbox table first. We’re wrapping the entity save and message storing in a single transaction so this operation is atomic. It will be published later through a background process called Message Relay. Good read!

[Read More]

Tags golang sql software-architecture app-development database