Files
llm-wiki/wiki/concepts/outbox-pattern.md

5.6 KiB

title, source_type, status, confidence, tags, related_projects, last_reviewed
title source_type status confidence tags related_projects last_reviewed
concept / Transactional Outbox Pattern llm-generated reviewed high
concept
ca-tmpl
messaging
kafka
outbox-pattern
ca-tmpl
2026-06-15

concept / Transactional Outbox Pattern

Summary

로컬 트랜잭션의 일부로 비즈니스 상태 변경과 이벤트를 동일한 데이터베이스(Outbox 테이블)에 저장한 후, 독립적인 프로세스(Outbox Relay)가 이 이벤트를 비동기적으로 메시지 브로커(Kafka 등)로 발행하는 디자인 패턴.

  • 이를 통해 분산 환경에서 비즈니스 로직 성공과 메시지 발행 간의 원자성(Atomicity)을 보장하고, 이중 쓰기(Dual-Write) 안티패턴을 방지한다.

Standard (공식 정의)

  • Dual-Write Anti-Pattern: 하나의 비즈니스 유스케이스 내에서 데이터베이스 업데이트와 외부 메시지 발행을 동시에 시도하는 방식. 데이터베이스 트랜잭션은 커밋되었으나 브로커 연결 실패로 메시지가 유실되거나, 반대로 메시지는 발행되었으나 데이터베이스 커밋이 롤백되는 불일치 문제가 상존한다.
  • Transactional Outbox:
    1. 비즈니스 원장 데이터 수정과 함께, 발행할 메시지를 동일 트랜잭션 하에서 Outbox 테이블에 인서트한다. (DB 로컬 트랜잭션의 원자성으로 인해 메시지 저장도 100% 보장된다.)
    2. 별도의 백그라운드 워커(Outbox Relay)가 Outbox 테이블을 주기적으로 폴링(또는 CDC를 활용)하여 PENDING 상태의 이벤트를 읽어온다.
    3. 릴레이 워커가 메시지를 브로커로 발행(Publish)한 뒤, 데이터베이스에 해당 Outbox 레코드를 COMPLETED 등으로 상태를 업데이트하거나 삭제한다.

한계 / 주의점

  • 중복 메시지 발행 (At-Least-Once Delivery): 릴레이가 브로커에 메시지를 정상적으로 보냈으나, DB에 상태를 COMPLETED로 업데이트하기 직전에 시스템이 다운되면 동일한 메시지가 재전송될 수 있다. 따라서 소비처(Consumer)는 반드시 멱등적 메시지 처리(Idempotent Consumer) 구조를 갖춰야 한다.
  • 순서 보장 (Ordering): 멀티 스레드로 릴레이를 돌릴 때 동일 Aggregate의 이벤트가 뒤집혀서 발행되지 않도록 Aggregate ID 기반의 분산 락이나 시퀀스 제어가 필요할 수 있다.

Project Application

  • wiki/explainer/adapter-outbound.md
  • 우리 프로젝트에서는 메시지 발행 시 직접 발행과 아웃복스 릴레이 발행의 결합을 지원함.
    • 직접 발행 (KafkaMessagePublisher): 비즈니스 트랜잭션 흐름 중 메시지를 즉시 발행함. 이미 로컬 DB 트랜잭션에 아웃복스가 커밋되므로, 실시간 발행은 Fail-Open 계약을 맺어 예외가 발생하더라도 사용자 API를 중단시키지 않고 백그라운드 릴레이에 유실 복구를 위임함.
    • 릴레이 발행 (KafkaOutboxMessagePublishAdapter): 백그라운드에서 Outbox 레코드를 전달받아 브로커에 실제 전달하는 역할. 브로커가 장애를 내면 반드시 예외를 다시 던지는 Fail-Closed 계약을 가짐. 예외가 전파되어야 릴레이 트랜잭션이 롤백되어 해당 레코드가 IN_FLIGHT에 고립되지 않고 재시도(Retry) 루프를 타거나 운영 경보(Runbook)가 정상 작동하기 때문임.

Claim-backed Knowledge

Knowledge Point Supporting Claims Confidence Notes
이중 쓰기(Dual-write)의 근본적 문제점과 일관성 결여 raw/official-docs/dual-write-antipattern-microservices-io.md high 마이크로서비스 데이터 패턴
트랜잭셔널 아웃복스 패턴의 기본 구성 요소 raw/official-docs/transactional-outbox-aws-prescriptive-guidance.md high AWS 마이크로서비스 설계 패턴
Outbox 데이터 상태 변경 및 중복 처리 주의점 raw/official-docs/microservices-io-transactional-outbox.md high Microservices.io 패턴 정의

내가 설명할 수 있어야 하는 것

  • 이중 쓰기(Dual-Write)의 위험성과 이를 아웃복스 패턴이 어떻게 해결하는지 메커니즘을 상세히 설명할 수 있어야 함.
  • 실시간 API 단의 메시지 발행기와 백그라운드 릴레이 단의 메시지 발행기가 예외 처리 정책(Fail-Open vs Fail-Closed)을 다르게 맺는 이유는 무엇인가?
  • 카프카 외에 다른 메시징 시스템(RabbitMQ, AWS SQS)으로 아웃복스 발행기를 대체하려면 어떻게 설계해야 하는가? (Port-Adapter 인터페이스 구현을 통해 어댑터만 교체)

Interview Questions

  • 메시지 큐와 RDB를 동시에 업데이트할 때 발생할 수 있는 데이터 정합성 문제와 이를 해결하기 위한 Transactional Outbox Pattern에 대해 설명해 주세요.
  • 아웃복스 릴레이 컴포넌트의 실패 상황 시 가용성과 정합성 설계 관점에서 어떻게 실패 복구를 처리해야 하는지 설명하십시오.

Do Not Overclaim

  • "아웃복스 패턴을 도입했으므로 분산 트레이싱 환경에서 완벽한 1회성 전송(Exactly-Once)을 달성할 수 있다"고 장담하면 안 된다. 분산 네트워크 상에서 릴레이 DB 업데이트 실패 시 중복 메시지가 무조건 나갈 수 있으므로, 최종 소비자의 멱등 수신 설계가 반드시 동반되어야 보장된다.

Sources