Files
llm-wiki/raw/official-docs/microservices-io-transactional-outbox.md
T

9.7 KiB

title, source_type, url, archive_url, status, confidence, tags, related_projects, related_branches, created, last_reviewed
title source_type url archive_url status confidence tags related_projects related_branches created last_reviewed
Transactional Outbox Pattern — microservices.io (Chris Richardson) official-doc https://microservices.io/patterns/data/transactional-outbox.html raw medium
architecture
transactional-outbox
dual-write
eventual-consistency
messaging
ca-skeleton-operational-contract
ca-skeleton-operational-contract
feature-repository-access-permission-contract
feature-domain-event-outbox-contract
2026-05-27 2026-05-27

Transactional Outbox Pattern — microservices.io (Chris Richardson)

Layer: raw/official-docs/ — Chris Richardson 의 microservices.io 패턴 카탈로그 중 "Transactional Outbox" 페이지 verbatim 발췌. dual-write 문제와 OUTBOX 테이블 기반 해결책의 1차 인용 출처.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-repository-access-permission-contract D7 (Repository 가 도메인 이벤트 발행 책임을 가질지, 아니면 outbox 테이블 write 만 책임지고 별도 relay 가 발행할지) 결정의 근거
raw/branch-notes/feature-domain-event-outbox-contract OUTBOX 테이블 + 별도 message relay 채택의 1차 근거 — "dual write 문제" 정의와 단일 local transaction 해결책

컨텍스트

ca-tmpl 이 도메인 이벤트를 어떻게 외부 메시지 브로커로 안전하게 전달할지의 청사진을 결정해야 한다. 가장 흔한 함정인 "DB commit 후 메시지 발행 실패" 또는 "메시지 발행 후 DB rollback" 의 inconsistency 를 방지하기 위한 표준 패턴이 transactional outbox. 본 raw 는 패턴 정의와 force/result 의 1차 출처.

출처 / Source

  • 원본 URL: https://microservices.io/patterns/data/transactional-outbox.html
  • 아카이브 URL:
  • 저자 / 조직: Chris Richardson — microservices.io (personal pattern catalog). 별도 vendor 의 공식 문서 아님.
  • 발행일: rolling docs (페이지에 "Copyright © 2026" 표기, 최초 작성 시점 명시는 없음)
  • 마지막 확인일: 2026-05-27

핵심 인용 / Key quotes (verbatim)

[§Context] "A service command typically needs to create/update/delete aggregates in the database and send messages/events to a message broker."

[§Context] "The command must atomically update the database and send messages in order to avoid data inconsistencies and bugs."

[§Problem] "How to atomically update the database and send messages to a message broker?"

[§Forces] "Messages must be sent to the message broker in the order they were sent by the service."

[§Solution] "The solution is for the service that sends the message to first store the message in the database as part of the transaction that updates the business entities."

[§Solution — message relay] "A separate process then sends the messages to the message broker."

[§Resulting context — benefits] "Messages are guaranteed to be sent if and only if the database transaction commits"

[§Resulting context — drawbacks] "Potentially error prone since the developer might forget to publish the message/event after updating the database."

Claims Extracted / 추출된 주장

Claim ID Claim Evidence quote Strength Applies to Does not prove
MSIO-OUTBOX-C1 service command 는 DB aggregate 변경 + 메시지 브로커로의 메시지 발행 두 가지를 함께 해야 하는 경우가 일반적 (dual-write 컨텍스트) [§Context] "A service command typically needs to create/update/delete aggregates in the database and send messages/events to a message broker." engineering-blog event-driven / SOA / microservices 의 command 흐름 모든 service command 가 메시지 발행을 동반해야 한다는 강제는 아님 — typically (일반적)
MSIO-OUTBOX-C2 DB update 와 메시지 발행이 atomic 하지 않으면 data inconsistency / bug 가 발생할 수 있음 [§Context] "The command must atomically update the database and send messages in order to avoid data inconsistencies and bugs." engineering-blog DB commit 과 broker publish 가 별개 트랜잭션인 모든 시나리오 어떤 종류의 inconsistency 가 어떤 빈도로 발생하는지의 정량적 근거는 본 인용에 없음
MSIO-OUTBOX-C3 핵심 문제는 "DB 와 메시지 브로커를 어떻게 atomic 하게 동시에 update 할 것인가" [§Problem] "How to atomically update the database and send messages to a message broker?" engineering-blog dual-write 문제 정의 2PC (XA) 같은 distributed transaction 이 부적절하다는 결론은 본 한 줄 인용으로 직접 입증 안 됨 — Forces 섹션과 결합 필요
MSIO-OUTBOX-C4 force: 메시지는 service 가 발행한 순서대로 브로커에 전달되어야 함 [§Forces] "Messages must be sent to the message broker in the order they were sent by the service." engineering-blog 순서 보장이 필요한 도메인 이벤트 (state machine 등) 모든 메시징 시나리오가 strict ordering 을 요구한다는 의미는 아님 — 본 force 가 적용되는 시스템에서만
MSIO-OUTBOX-C5 해법: 발행할 메시지를 business entity 를 update 하는 동일 트랜잭션의 일부로 DB 에 먼저 저장 [§Solution] "The solution is for the service that sends the message to first store the message in the database as part of the transaction that updates the business entities." engineering-blog OUTBOX 테이블 구현 시 메시지 저장 테이블이 반드시 "OUTBOX" 라는 이름이어야 한다는 강제는 아님 (관습일 뿐)
MSIO-OUTBOX-C6 별도 process (message relay) 가 저장된 메시지를 브로커로 발행 [§Solution] "A separate process then sends the messages to the message broker." engineering-blog polling publisher / transaction log tailing 등 relay 구현 relay 가 별도 OS 프로세스여야 한다는 강제는 아님 — 동일 서비스 내 별도 스레드/스케줄러도 일반적
MSIO-OUTBOX-C7 benefit: 메시지는 DB 트랜잭션이 commit 된 경우에 한해 그리고 그 경우에만 발행이 보장됨 (if and only if) [§Resulting context — benefits] "Messages are guaranteed to be sent if and only if the database transaction commits" engineering-blog at-least-once delivery + 일관성 보장 평가 exactly-once 까지 보장된다는 의미는 아님 — relay 가 동일 메시지를 재발행할 수 있으므로 consumer 측 idempotency 필요
MSIO-OUTBOX-C8 drawback: 개발자가 DB update 후 메시지/이벤트 발행을 잊을 수 있어 error-prone [§Resulting context — drawbacks] "Potentially error prone since the developer might forget to publish the message/event after updating the database." engineering-blog outbox write 가 application code 의 명시적 호출에 의존하는 구현 모든 outbox 구현이 error-prone 하다는 의미는 아님 — 도메인 이벤트 자동 수집 (e.g., Spring Data domain events / aspect) 으로 완화 가능

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • MSIO-OUTBOX-C1~C3: dual-write 문제의 정의 + atomicity 요구
    • MSIO-OUTBOX-C4: ordering force
    • MSIO-OUTBOX-C5~C6: 해법의 두 축 (OUTBOX 저장 + 별도 relay)
    • MSIO-OUTBOX-C7~C8: benefit (commit 과 발행의 if-and-only-if 보장) 과 drawback (forget-to-publish)
  • 이 자료가 증명하지 않는 것:
    • 본 페이지가 공식 vendor doc 이라는 점 — microservices.io 는 Chris Richardson 의 personal pattern catalog. AWS/Spring/Confluent 등의 공식 채택을 의미하지 않음. strength engineering-blog.
    • 특정 구현 (Debezium / Spring Modulith / Eventuate / 자체 polling) 이 정답이라는 결론
    • 메시지 브로커가 반드시 Kafka 여야 한다는 점 (RabbitMQ / SQS / Pulsar 모두 동일 패턴 적용 가능)
    • exactly-once delivery 보장 — C7 의 "if and only if" 는 DB-쪽 보장이며, consumer 측 idempotency 와 독립
    • outbox 테이블 schema 의 정확한 컬럼 구성 (id, aggregate_id, type, payload, created_at 등은 관습)
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 이 polling publisher / transaction log tailing 중 어느 변형을 default 로 채택할지 (raw/branch-notes/feature-domain-event-outbox-contract)
    • 도메인 이벤트 수집 메커니즘 (Aggregate.registerEvent → Repository.save 시 함께 outbox insert) 의 구체 설계
    • consumer 측 idempotency 보장 정책

메모 / Notes

  • 본 패턴은 Microservices Patterns (Chris Richardson, Manning 2018) 책에도 동일 내용 수록. 책이 더 상세하지만 본 페이지가 가장 자주 인용되는 단일 URL.
  • microservices.io 가 personal blog 임에도 패턴 카탈로그로서 사실상 표준 참조로 사용되는 경우가 많음. 그러나 본 wiki 의 strength 분류 기준에서는 engineering-blog 가 정확 — 공식 vendor doc / 표준이 아니므로.
  • "공식 best practice" 로 인용하려면 동일 패턴을 다루는 official-vendor-doc (예: AWS Prescriptive Guidance, Microsoft Cloud Design Patterns) 와 corroborate 해야 함.