Files
llm-wiki/raw/official-docs/outbox-skip-locked-microservices-io.md

11 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
ca-outbox-pattern
outbox
skip-locked
polling
baseline
microservices-io
official-doc
ca-skeleton-operational-contract
feature-domain-event-outbox-contract
feature-background-job-async-contract
2026-05-22 2026-05-27

Transactional Outbox Pattern (microservices.io)

Layer: raw/official-docs/ — Chris Richardson microservices.io "Pattern: Transactional outbox" 의 원문 발췌·출처 기록. ca-tmpl 이 채택한 DB outbox + polling + FOR UPDATE SKIP LOCKED 결정의 baseline 정의 문서. 다른 대안들과 비교할 기준점.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-domain-event-outbox-contract Topic 3 — Outbox Pattern baseline 채택 (SKIP LOCKED polling) 의 1차 근거 — Chris Richardson 원형 정의
raw/branch-notes/feature-background-job-async-contract Background job / async event 발행에서 outbox + polling 으로 dual-write 회피 결정 근거
raw/project-notes/ca-skeleton-operational-contract §18 (Control Plane Contract) / §19 (Domain Application Readiness Contract) 의 outbox 발행 채택안 baseline

컨텍스트

ca-tmpl 이 채택한 DB outbox + polling + FOR UPDATE SKIP LOCKED 결정의 baseline 정의 문서. business write + event write 를 동일 트랜잭션 안에서 묶고, 별도 Message Relay 가 outbox 를 polling 하여 broker 로 발행하는 패턴.

출처 / Source

  • 원본 URL: https://microservices.io/patterns/data/transactional-outbox.html
  • 보조 URL (Polling publisher 패턴): https://microservices.io/patterns/data/polling-publisher.html
  • 아카이브 URL: (미수집)
  • 저자 / 조직: Chris Richardson — microservices.io
  • 발행일: rolling docs (페이지 자체에 명시 없음)
  • 마지막 확인일 (capture): 2026-05-22
  • 마지막 재검증 시도: 2026-05-27
  • [2026-05-25 capture]: user 가 2026-05-22 수집한 인용 원형 유지 (재검증 보류 마커는 2026-05-25 부여된 상태).
  • 재검증 결과 [2026-05-27 verified attempt]:
    • 1차 URL https://microservices.io/patterns/data/transactional-outbox.html WebFetch 성공. 페이지에는 "Pattern: Transactional outbox" 제목 + Context/Problem/Forces/Solution/Result context/Related patterns/Learn more 섹션 존재.
    • C1 (Solution): user 수집본 verbatim 과 불일치. 실제 페이지 표현은 "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." → 의미는 동일하나 wording 다름. → user 수집본은 paraphrase 로 reclassify.
    • C2 (Message Relay): 부분 일치. 실제 페이지 "A separate process then sends the messages to the message broker." → wording 차이.
    • C3, C4 (Polling drawback, SKIP LOCKED): 1차 URL 의 본문 발췌에서 NOT FOUND. 보조 페이지 https://microservices.io/patterns/data/polling-publisher.html 도 WebFetch 했으나 두 문장 모두 NOT FOUND (해당 페이지는 high-level pattern description 만 포함).
  • 재검증 한계: WebFetch 페이지 발췌 범위가 항상 페이지 전체를 노출하지는 않을 수 있어 NOT FOUND 가 absence 의 결정적 증거는 아니나, 4개 quote 모두 verbatim 형태로 확인되지 않음 → 본 문서 인용은 모두 needs-confirmation Strength 유지 (Strength 상향 없음). C1/C2 는 paraphrase 가능성 노출, C3/C4 는 출처 페이지 재확정 필요.

핵심 인용 / Key quotes (verbatim claimed, user 수집본 [2026-05-25 capture] — [2026-05-27 verified attempt] verbatim 재확인 실패 / NOT FOUND, 아래 §재검증 결과 참조)

[§Transactional outbox — Solution] "As part of the database transaction that updates the business entity, the service inserts a message into an OUTBOX table." — [2026-05-27 verified attempt]: 실제 페이지 wording 은 "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." → 의미 동일, verbatim 불일치 → paraphrase 로 처리.

[§Message Relay] "A separate Message Relay process publishes the events inserted into database to a message broker." — [2026-05-27 verified attempt]: 실제 페이지 표현 "A separate process then sends the messages to the message broker." → 부분 일치, wording 차이.

[§Polling publisher — Drawback] "Polling the database is a simple approach that works reasonably well at low scale. The disadvantage is that frequently polling the database can be expensive." — [2026-05-27 verified attempt]: 1차 URL 및 보조 페이지 polling-publisher.html 본문 발췌에서 NOT FOUND.

[§SKIP LOCKED parallelism] "Some databases, such as PostgreSQL and MySQL, support the SKIP LOCKED clause which enables multiple instances of the Message Relay to safely poll the OUTBOX table in parallel." — [2026-05-27 verified attempt]: 1차 URL 및 보조 페이지 polling-publisher.html 본문 발췌에서 NOT FOUND.

Claims Extracted / 추출된 주장

본 raw 의 모든 quote 는 2026-05-22 user 수집본이며 2026-05-27 WebFetch 차단으로 verbatim 재확인 보류 → 전체 needs-confirmation.

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
OUTBOX-MIO-C1 business entity 를 변경하는 DB 트랜잭션의 일부로 OUTBOX 테이블에 메시지를 insert 한다 (원자성 확보) [§Transactional outbox — Solution] "As part of the database transaction that updates the business entity, the service inserts a message into an OUTBOX table." needs-confirmation 단일 RDB 트랜잭션으로 business write + outbox write 가 가능한 모든 환경 OUTBOX 스키마 (payload, aggregate_id, status 등) 의 구체적 컬럼 설계는 본 인용에 포함되지 않음
OUTBOX-MIO-C2 OUTBOX 테이블의 이벤트를 broker 로 발행하는 별도의 Message Relay 프로세스가 존재한다 [§Message Relay] "A separate Message Relay process publishes the events inserted into database to a message broker." needs-confirmation outbox 패턴의 모든 변형 (polling, CDC 모두 Message Relay 를 가짐) Message Relay 가 polling 인지 CDC 인지 본 인용은 중립 — 둘 다 가능
OUTBOX-MIO-C3 DB polling 방식은 단순하며 저-규모에서 합리적으로 동작하나, 자주 polling 하면 비용이 비싸다 [§Polling publisher — Drawback] "Polling the database is a simple approach that works reasonably well at low scale. The disadvantage is that frequently polling the database can be expensive." needs-confirmation RDB outbox + polling Message Relay 변형 "low scale" / "expensive" 의 정확한 임계 (TPS, interval) 는 본 인용에 없음 — 환경별 측정 필요
OUTBOX-MIO-C4 PostgreSQL 과 MySQL 같은 일부 DB 는 SKIP LOCKED 절을 지원하며, 이로 인해 여러 Message Relay 인스턴스가 OUTBOX 테이블을 병렬로 안전하게 polling 할 수 있다 [§SKIP LOCKED parallelism] "Some databases, such as PostgreSQL and MySQL, support the SKIP LOCKED clause which enables multiple instances of the Message Relay to safely poll the OUTBOX table in parallel." needs-confirmation Postgres 9.5+ / MySQL 8.0+ 환경 "safely poll in parallel" 이 순서 보장을 포함하지 않음 — 본 인용은 "안전" = lock contention 회피 의미만

Strength 정책

본 문서의 모든 claim 은 needs-confirmation. 이유: 2026-05-27 재검증 시점에 WebFetch 가 차단되어 user 수집본 (2026-05-22) 의 verbatim 일치 여부를 공식 페이지 대조로 확인 못함. wiki 승급 전 재확인 필수.

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것 (재확인 시):
    • OUTBOX-MIO-C1: outbox 패턴의 핵심 — business write + outbox write 의 트랜잭션적 결합
    • OUTBOX-MIO-C2: Message Relay 분리 (구체 구현은 polling/CDC 중립)
    • OUTBOX-MIO-C3: polling 의 trade-off (단순성 vs 비용)
    • OUTBOX-MIO-C4: SKIP LOCKED 가 polling Message Relay 의 수평 확장 메커니즘
  • 이 자료가 증명하지 않는 것:
    • outbox + polling 의 정확한 lag 수치
    • OUTBOX schema 설계 (payload, status flag, partition key)
    • SKIP LOCKED 가 순서 보장을 제공한다는 주장 (오히려 본 인용 + skip-locked-postgres-docs 의 "inconsistent view" 와 결합 시 순서 비보장)
    • exactly-once delivery — outbox + polling 은 at-least-once (별도 근거 필요)
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 의 polling interval 결정 (TPS · lag · DB 부하 균형)
    • 다중 publisher 인스턴스 수 (운영 단순성 vs 처리량)
    • outbox archive / partition / vacuum 정책 (hot table 방지)

메모 / Notes (내 프로젝트 해석 — 직접 인용 아님)

  • 적용 시나리오: 모놀리식 / MSA 모두. CDC 인프라가 없거나 도입을 미루고 싶을 때, 한 DB 트랜잭션 안에서 business write + event write 를 묶고 싶을 때.
  • 장점:
    • 인프라 추가 없음 (DB 만 있으면 됨)
    • business write 와 event write 의 원자성 보장 → dual-write 문제 회피
    • SKIP LOCKED 로 다중 publisher 인스턴스 수평 확장 가능
    • 구현 단순, 디버깅 쉬움 (SQL 로 직접 확인 가능)
  • 단점:
    • polling lag (interval 만큼 지연)
    • polling 부하 (interval 을 줄이면 DB I/O 증가)
    • outbox 테이블이 hot table 이 되기 쉬움 → 주기적 archive/delete 필요
    • 순서 보장은 publisher 단일 인스턴스 또는 partition key 설계가 필요
  • ca-tmpl (SKIP LOCKED polling) 과의 차이: 동일 패턴. baseline.
  • 운영 복잡도: 낮음. 추가 컴포넌트 없음.
  • exactly-once / at-least-once 보장 수준: at-least-once. broker 발행 후 outbox row 삭제/마킹 사이에 크래시 시 중복 발행 가능 → consumer 측 idempotency 필수.
  • 외부 의존성 추가 여부: 없음.
  • 대안 그룹 (Topic 3 — Outbox Pattern, 대안 6종): SKIP LOCKED polling / Debezium CDC / Kafka Connect SMT / Dual-write [금지] / Event sourcing / Spring @TransactionalEventListener
  • 본 source 의 위치: ca-tmpl 채택안 baseline (SKIP LOCKED polling, Chris Richardson 원형)