Etc

[트랜잭션] 3. Outbox Pattern

azzure 2025. 4. 4. 18:57


1. Outbox Pattern

MSA 환경에서 데이터베이스와 메시지 브로커(RabbitMQ, Kafka 등) 간의 일관성을 유지하기 위한 패턴이다

트랜잭션을 사용하는 데이터베이스의 ACID 속성을 활용하여, 메시지 송신의 신뢰성을 보장하는 방식이다

 

1-1. Outbox Pattern이 필요한 이유

MSA에서 발생하는 문제

  • 데이터베이스에 데이터를 저장한 이후, 메시지 브로커에 이벤트를 보내야 하는 상황이 많은데,
  • 데이터베이스 저장과 메시지 브로커 송신을 하나의 트랜잭션으로 묶을 수 없다
  • 즉, 데이터베이스에 데이터를 저장한 이후, 메시지를 보내는 중에 애플리케이션 장애가 발생한다면 데이터 불일치 문제가 생길 수 있다는 것이다

2. Outbox Pattern의 핵심 원리

메시지를 브로커로 직접 보내지 않고, 데이터베이스의 별도 테이블 (Outbox 테이블)에 먼저 저장하는 방식이다

이후 비동기 프로세스가 테이블에서 메시지를 읽어 브로커로 전송하는 구조이다

 

2-1. Outbox Pattern의 핵심 개념

  • DB 트랜잭션과 메시지 저장을 함께 처리 (일관성 보장)
  • 메시지 브로커 송신은 비동기 프로세스로 처리 (장애 발생 시 재시도 가능)

 

2-2. Outbox Pattern 구현 흐름

  • 서비스가 데이터베이스에 데이터를 저장하면서 같은 트랜잭션 내에서 Outbox 테이블에 이벤트도 함께 저장
  • 별도의 Outbox 메시지 프로세서 (Polling Consumer) 가 Outbox 테이블을 주기적으로 조회
  • Outbox 테이블의 메시지를 읽어 Kafka, RabbitMQ 등 메시지 브로커로 전송
  • 전송이 완료되면 해당 메시지를 Outbox 테이블에서 삭제 (또는 처리 완료 상태로 변경)

 

2-3. 메시지 프로세서

Outbox 테이블을 주기적으로 조회해 메시지 브로커(RabbitMQ, Kafka 등)로 전송하는 역할을 하는 컴포넌트이다.

이 프로세스는 Polling 방식 혹은 CDC 방식으로 동작할 수 있다

 

메시지 프로세서 동작 흐름

  • 서비스가 데이터를 저장하면서 같은 트랜잭션 내에서 Outbox 테이블에 이벤트 저장
  • 메시지 프로세서가 Outbox 테이블을 주기적으로 조회 (Polling) 또는 DB 변경 감지 (CDC)
  • 메시지 프로세서가 메시지를 읽어 Kafka/RabbitMQ로 전송
  • 전송이 완료되면 해당 메시지를 Outbox 테이블에서 삭제 또는 처리 완료 상태로 변경

Polling과 CDC

  • Polling
    • 일정 주기마다 데이터베이스를 조회하여 변경된 데이터를 가져오는 방식이다
    • 쿼리를 주기적으로 실행하고, 구현이 비교적 간단하다
    • 다만 데이터 변경 후 전파까지 지연이 있을 수 있으며, 데이터베이스 부하 문제가 생길 수 있다
  • CDC (Change Data Capture)
    • 데이터베이스 변경 로그(change log)를 감지하여 변경 사항을 실시간으로 전파하는 방식이다
    • 트랜잭션 로그를 읽어 변경 사항을 감지하고, 데이터 변경 발생 즉시 감지하여 실시간 데이터 반영이 가능하다
    • 트랜잭션 로그를 읽으므로 추가 쿼리 실행 부담이 없지만, 추가적인 CDC 툴이 필요하다

3. Outbox Pattern의 장단점

3-1. 장점

  • 데이터 정합성 보장 → DB 저장과 이벤트 저장이 같은 트랜잭션으로 수행된다
  • 장애 복구 가능 → 메시지 브로커 전송 중 장애 발생해도 Outbox 테이블에 데이터가 남아 있다
  • 재시도 가능 → 메시지 프로세서가 실패한 메시지를 다시 읽고 전송이 가능하다

3-2. 단점

  • Outbox 테이블을 읽고 삭제하는 별도 프로세스가 필요하다 (Polling 방식)
  • 지연 전파 가능성 → 메시지 브로커 전송이 비동기적이라 실시간보다는 약간의 딜레이가 발생할 수 있다

참고

- https://velog.io/@eastperson/Transaction-Outbox-Pattern-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

- https://parkhyeokjin.github.io/spring/2024/06/11/trasactionOutboxPattern.html

- https://devocean.sk.com/blog/techBoardDetail.do?ID=165445&boardType=techBlog