Spring 기반 Transactional Outbox · Inbox

Spring 기반 Transactional Outbox · Inbox A data-flow diagram generated by Archify. 01 / 요청 02 / Producer 트랜잭션 03 / Outbox 전달 04 / Kafka 05 / Consumer 트랜잭션 클라이언트 · 주문 생성 요청 · 01 / 요청 · HTTP 클라이언트 주문 생성 요청 HTTP Spring 주문 서비스 · @Transactional · 02 / Producer 트랜잭션 · JPA Spring 주문 서비스 @Transactional JPA Orders + Outbox · 한 DB 트랜잭션 · 02 / Producer 트랜잭션 · @Version Orders + Outbox 한 DB 트랜잭션 @Version Outbox Relay · Polling 또는 CDC · 03 / Outbox 전달 · retry Outbox Relay Polling 또는 CDC retry Redis · lease · hot dedupe · 03 / Outbox 전달 · 보조 계층 Redis lease · hot dedupe 보조 계층 Kafka Topic · aggregate_id 파티션 키 · 04 / Kafka · at-least-once Kafka Topic aggregate_id 파티션 키 at-least-once Dead Letter Topic · 격리 후 승인 재처리 · 04 / Kafka · 운영 소유 Dead Letter Topic 격리 후 승인 재처리 운영 소유 Spring Kafka Consumer · 수동 ACK · 재시도 · 05 / Consumer 트랜잭션 · group.id Spring Kafka Consumer 수동 ACK · 재시도 group.id Inbox + Domain State · 같은 로컬 트랜잭션 · 05 / Consumer 트랜잭션 · UNIQUE message_id Inbox + Domain State 같은 로컬 트랜잭션 UNIQUE message_id 외부 API · 결제 · 이메일 · 05 / Consumer 트랜잭션 · idempotency key 외부 API 결제 · 이메일 idempotency key POST /orders 동기 요청 주문 + 이벤트 원자 저장 local ACID 미발행 이벤트 조회 poll / CDC 선택적 lease · 캐시 정합성 원장 아님 OrderCreated 중복 가능 poll 후 처리 ACK는 commit 뒤 Inbox 기록 + 상태 변경 local ACID 재시도 소진 메시지 dead letter 안전한 후속 작업 고정 idempotency key Legend primary data policy / PII async batch data store data flow

원자성 경계

  • • orders와 outbox를 한 DB 트랜잭션으로 커밋
  • • inbox와 소비자 도메인 변경도 한 트랜잭션으로 커밋
  • • Kafka·Redis·DB를 하나의 XA처럼 취급하지 않음

동시성과 중복

  • • 도메인 엔티티의 @Version으로 lost update 차단
  • • Inbox의 UNIQUE(consumer, message_id)가 최종 중복 방어
  • • Redis는 빠른 거르기와 relay lease에만 사용

운영 계약

  • • aggregate_id를 Kafka key로 사용해 개체별 순서 유지
  • • outbox lag·중복률·낙관적 락 충돌·DLT를 계측
  • • 외부 API에는 이벤트 ID 기반 idempotency key 전달