--- title: Event Sourcing as an Alternative to Outbox (microservices.io) source_type: official-doc url: https://microservices.io/patterns/data/event-sourcing.html archive_url: status: raw confidence: high tags: [ca-outbox-pattern, event-sourcing, alternative, microservices-io, official-doc] related_branches: [feature-domain-event-outbox-contract, feature-background-job-async-contract] related_projects: [ca-skeleton-operational-contract] created: 2026-05-22 last_reviewed: 2026-05-27 --- # Event Sourcing as an Alternative to Outbox (microservices.io) > Layer: `raw/official-docs/` — microservices.io 의 "Pattern: Event sourcing" 문서. ca-tmpl outbox 대안 중 **대안 4 (event sourcing — 도메인 모델 자체 교체)** 의 1차 근거. ## Parent / 활용 branch (필수) | Branch | 이 자료가 정당화하는 결정 | |---|---| | [[raw/branch-notes/feature-domain-event-outbox-contract]] | outbox 6대안 비교에서 "event sourcing" 위치 — outbox 자체가 불요해지는 모델로 분류하는 근거 | | [[raw/branch-notes/feature-background-job-async-contract]] | event 발행을 background job 으로 처리할지 vs event store 내장 subscriber 로 처리할지의 분기 근거 | 특정 branch 없이 foundational 조사로 수집한 경우: - [[raw/project-notes/ca-skeleton-operational-contract]] — Contract #19 (Domain Application Readiness Contract) 의 Domain Event / Outbox 항목에서 event sourcing 채택 안 함의 근거 자료 ## 컨텍스트 ca-tmpl 의 SKIP LOCKED outbox 결정에 대한 **대안 4: event sourcing**. outbox 자체가 불요해지는 모델 — event store 가 source of truth 가 되므로 별도 발행 메커니즘이 필요 없거나 매우 단순해짐. ## 출처 / Source - 원본 URL: https://microservices.io/patterns/data/event-sourcing.html - 아카이브 URL: (미수집) - 저자 / 조직: Chris Richardson (microservices.io) - 발행일: rolling (microservices.io patterns catalog) - 마지막 확인일: 2026-05-27 - 보조 자료: Confluent blog "Event Sourcing, CQRS, and Stream Processing" (`https://www.confluent.io/blog/event-sourcing-cqrs-stream-processing-apache-kafka-whats-connection/`) ## 핵심 인용 / Key quotes (verbatim) > [§Solution] "Event sourcing persists the state of a business entity such an Order or a Customer as a sequence of state-changing events." > [§Solution] "Whenever the state of a business entity changes, a new event is appended to the list of events." > [§Solution] "Since saving an event is a single operation, it is inherently atomic." > [§Solution] "The application reconstructs an entity's current state by replaying the events." > [§Solution] "When a service saves an event in the event store, it is delivered to all interested subscribers." > [§Resulting Context — Benefits] "It solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes." > [§Resulting Context — Drawbacks] "The event store is difficult to query since it requires typical queries to reconstruct the state of the business entities." 보조 인용 (Confluent blog, 동일 주제): > [Confluent — Event Sourcing, CQRS, and Stream Processing] "Event sourcing involves modeling the state changes made by applications as an immutable sequence or 'log' of events." ## Claims Extracted / 추출된 주장 | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | ES-OUTBOX-C1 | Event sourcing 은 business entity 의 state 를 일련의 state-changing events 의 sequence 로 영속화한다 | [§Solution] "Event sourcing persists the state of a business entity such an Order or a Customer as a sequence of state-changing events." | `official-reference` | event sourcing 채택 시스템의 영속화 모델 정의 | event sourcing 이 모든 도메인에 적합하다는 뜻은 아님 — drawback 인용 별도 | | ES-OUTBOX-C2 | event 저장은 단일 operation 이므로 본질적으로 atomic — 즉 dual-write 문제가 발생하지 않는 구조 | [§Solution] "Since saving an event is a single operation, it is inherently atomic." | `official-reference` | event store 가 단일 transaction 단위로 event 를 추가하는 영속화 경계 | "DB + Kafka 두 시스템에 동시 쓰기가 자동으로 atomic" 이라는 뜻은 아님 — event store 단일 시스템 내부에서만 | | ES-OUTBOX-C3 | 현재 상태는 events 를 replay 함으로써 재구성된다 (저장된 것은 events, 계산되는 것은 state) | [§Solution] "The application reconstructs an entity's current state by replaying the events." | `official-reference` | event sourcing 의 read path 메커니즘 | replay 비용이 항상 허용 가능하다는 뜻은 아님 — snapshot 필요성은 별도 | | ES-OUTBOX-C4 | event store 에 event 가 저장되면 모든 관심 있는 subscriber 에게 전달된다 → 별도 발행 메커니즘(outbox/CDC) 의 역할이 event store 자체로 흡수 | [§Solution] "When a service saves an event in the event store, it is delivered to all interested subscribers." | `official-reference` | event store 가 내장 subscription 기능을 제공하는 구현 (EventStoreDB, Axon 등) | "subscriber 전달이 exactly-once" 라는 뜻은 아님 — delivery semantics 본 인용에 미명시 | | ES-OUTBOX-C5 | event sourcing 은 event-driven architecture 구현의 핵심 문제(상태 변경 시 안정적 event 발행) 를 해결한다 | [§Resulting Context — Benefits] "It solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes." | `official-reference` | event-driven architecture 의 dual-write 문제 컨텍스트 | "outbox 보다 항상 우수하다" 는 뜻은 아님 — 트레이드오프 별도 | | ES-OUTBOX-C6 | event store 는 query 가 어렵다 — 일반 query 가 entity state 재구성을 요구하기 때문 | [§Resulting Context — Drawbacks] "The event store is difficult to query since it requires typical queries to reconstruct the state of the business entities." | `official-reference` | event sourcing 의 read model 운영 부담 | CQRS read model 분리가 의무라는 뜻은 아님 — 권장 패턴일 뿐 | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것**: - `ES-OUTBOX-C1` ~ `C3`: event sourcing 의 정의·atomicity·replay 메커니즘 - `ES-OUTBOX-C4` ~ `C5`: event sourcing 이 outbox 와 같은 별도 발행 메커니즘의 필요성을 흡수한다는 사실 - `ES-OUTBOX-C6`: event sourcing 의 query 어려움 (CQRS / snapshot / projection 필요성의 근거) - **이 자료가 증명하지 않는 것**: - event sourcing 이 outbox/SKIP LOCKED 보다 "더 나은 선택" 이라는 일반적 권고 - 기존 CRUD 시스템에서 event sourcing 으로 마이그레이션 비용 구체적 산정 - event store 의 EOS (exactly-once) 보장 — 본 페이지는 delivery semantics 미명시 - Spring/JPA 기반 도메인에서 event sourcing 도입의 ORM 충돌 정도 - **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: - ca-tmpl 의 도메인이 event sourcing 에 적합한가 (금융/감사 로그 중심 vs 단순 CRUD) - team 의 CQRS/projection 운영 경험 수준 — event sourcing 학습 곡선 평가 - event store 도구 선택 (EventStoreDB / Axon / Kafka-as-log) 의 운영 비용 ## 메모 / Notes (내 프로젝트 해석) > 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석. - 적용 시나리오: 도메인이 본질적으로 event-driven (금융 거래, 주문 상태 전이, 감사 로그가 핵심). 팀이 CQRS / projection 운영에 익숙한 경우. - 장점: - **outbox 불요** — event 자체가 저장 단위 (`ES-OUTBOX-C2` + `C4` 결합 해석) - 완전한 audit log (모든 상태 변화가 보존) - replay 로 신규 read model 구축 자유로움 - temporal query (과거 시점 상태 재구성) 가능 - 단점: - **현재 상태 조회가 비싸다** (`ES-OUTBOX-C6`) → snapshot / projection 인프라 필요 - 학습 곡선 가파름 (CQRS, eventual consistency, projection 재구축 등) - schema evolution (event 버전 관리) 부담 - 기존 CRUD 시스템에서 마이그레이션 비용 큼 - 일반적 ORM/JPA workflow 와 충돌 - ca-tmpl(SKIP LOCKED polling) 과의 차이: - outbox 는 **기존 CRUD + 이벤트 발행** 하이브리드. event sourcing 은 **저장 모델 자체를 교체**. - "보조 발행 메커니즘" 이 아니라 "도메인 모델 패러다임 전환" 이라 의사결정 스케일이 다름 - 운영 복잡도: 높음. event store + projection + snapshot 운영. - exactly-once / at-least-once 보장 수준: 발행은 여전히 **at-least-once** 가정 안전 (본 페이지 미명시 — 별도 검증 필요). - 외부 의존성 추가 여부: event store (EventStoreDB, Kafka as log, Axon 등) 또는 자체 구축. - 결론: ca-tmpl 같은 기존 CRUD-based 도메인에 event sourcing 을 도입하는 것은 outbox 의 "대안" 이 아니라 "전혀 다른 도메인 설계 선택" 에 가까움. 트레이드오프 폭이 가장 큼. ## Related / 관련 - 같은 주제 다른 raw 자료: - [[raw/company-tech-blogs/domain-event-sourcing-vs-cqrs-greg-young]] (event sourcing vs CQRS 구분 — Greg Young 원작자) - [[raw/company-tech-blogs/outbox-confluent-kafka-connect-smt]] (대안 2: Kafka Connect SMT) - [[raw/company-tech-blogs/outbox-netflix-domain-events-cdc]] (대안 6: Netflix DBLog) - [[raw/company-tech-blogs/outbox-wix-engineering-debezium]] (대안 1 사례: Wix Debezium production) - 인용하는 branch: - [[raw/branch-notes/feature-domain-event-outbox-contract]] - [[raw/branch-notes/feature-background-job-async-contract]] - 인용하는 wiki: (미작성)