피드로 돌아가기
Dev.toBackend
원문 읽기
Transactional Outbox 패턴을 통한 분산 시스템 데이터 정합성 및 내구성 확보
Your MediatR Command Just Lost an Email. Here's Why.
AI 요약
Context
MediatR의 In-process 동기 디스패치 특성으로 인해 DB 트랜잭션과 외부 API 호출이 동일한 스레드 및 트랜잭션 범위 내에서 실행되는 구조적 한계 존재. SMTP 타임아웃 등 외부 서비스 장애 발생 시 비즈니스 데이터까지 함께 Rollback 되거나, 결제 완료 후 알림 발송이 누락되는 데이터 불일치 문제 발생.
Technical Solution
- Transactional Outbox 패턴 도입을 통한 비즈니스 상태 변경과 메시지 발행의 원자성(Atomicity) 보장
- DB SaveChanges 호출 시 비즈니스 행과 Outbox 테이블에 메시지를 동시에 기록하는 단일 트랜잭션 설계
- 별도의 Dispatcher 워커가 Outbox 테이블을 폴링하여 메시지를 비동기적으로 처리하고 완료 후 삭제하는 구조 채택
- Wolverine 프레임워크를 활용해 PostgreSQL을 메시지 전송 계층(Transport)으로 사용하여 별도의 Broker 없이 인프라 복잡도 제거
- *Event(In-process, Best-effort)와 *Eto(Durable, Integration Event)라는 명명 규칙을 도입해 내구성 경계(Durability Boundary)를 타입 수준에서 명시
- 아키텍처 테스트를 통해 도메인 내부 이벤트와 외부 통합 이벤트의 혼용을 방지하는 강제 제약 사항 적용
실천 포인트
- 외부 시스템 호출(Email, Webhook, 3rd Party API)이 포함된 커맨드 핸들러에 MediatR 같은 단순 디스패처를 사용하고 있는지 검토 - 'DB 커밋 성공 + 사이드 이펙트 실패' 시나리오에 대한 복구 전략(Retry, DLQ)이 마련되어 있는지 확인 - 메시지 브로커 도입 전, RDBMS를 활용한 Outbox 패턴으로 인프라 비용과 운영 복잡도를 낮출 수 있는지 분석 - 이벤트의 성격에 따라 내부 전파용과 외부 통합용 타입을 분리하여 설계했는지 체크