Categories: Camel프레임워크

[Camel in Action] 11-2. Camel 트랜잭션 처리 – 분산 시스템에서 데이터 일관성 보장

분산 시스템에서 트랜잭션이 어려운 이유

단일 데이터베이스의 트랜잭션은 ACID를 보장합니다. 하지만 JMS 큐 + 데이터베이스를 동시에 사용할 때는 두 시스템을 하나의 트랜잭션으로 묶어야 합니다. 이것이 분산 트랜잭션 문제입니다.

JMS 트랜잭션 설정

JMS 컴포넌트에 transacted=true를 설정하면 메시지 수신과 처리를 하나의 JMS 트랜잭션으로 묶습니다.

from("activemq:queue:orders?transacted=true")
  .transacted()
  .process(exchange -> {
    // 처리 중 예외 발생 시 JMS 트랜잭션 자동 롤백
    // 메시지가 큐로 다시 돌아감
    orderService.process(exchange.getIn().getBody(Order.class));
  })
  .to("activemq:queue:confirmed-orders");

JMS + DB 동시 트랜잭션

JMS 메시지를 받아 DB에 저장하는 작업을 하나의 트랜잭션으로 처리하려면 JTA(Java Transaction API) 트랜잭션 매니저가 필요합니다.

// Spring XML 설정
<bean id="jtaTransactionManager"
  class="org.springframework.transaction.jta.JtaTransactionManager"/>

<camelContext>
  <route>
    <from uri="activemq:queue:orders?transacted=true"/>
    <transacted ref="jtaTransactionManager"/>
    <to uri="bean:orderService?method=saveOrder"/>
    <to uri="activemq:queue:order-confirmed"/>
  </route>
</camelContext>

JTA는 강력하지만 2PC(2-Phase Commit) 프로토콜로 인해 성능 부담이 있습니다. 모든 시스템이 XA 트랜잭션을 지원해야 합니다.

Idempotent Consumer – 중복 처리 방지

네트워크 오류로 메시지가 재전송될 때 같은 메시지를 두 번 처리하는 것을 막는 패턴입니다.

from("activemq:queue:payments")
  .idempotentConsumer(
    header("paymentId"),
    JdbcMessageIdRepository.jpaMessageIdRepository(dataSource, "payments"))
  .process(exchange -> {
    // paymentId가 처음 본 것일 때만 이 코드가 실행됨
    paymentService.process(exchange.getIn().getBody());
  });

처리한 메시지 ID를 DB나 Redis에 저장하고, 다음에 같은 ID가 오면 건너뜁니다.

SAGA 패턴 – 분산 트랜잭션의 현대적 대안

마이크로서비스 환경에서 JTA를 쓰기 어려울 때 SAGA 패턴이 대안입니다. 각 단계가 성공하면 다음 단계로, 실패하면 이전 단계를 보상(compensate)하는 방식입니다.

// Camel SAGA EIP
from("direct:placeOrder")
  .saga()
    .to("direct:reserveInventory")
    .to("direct:processPayment")
    .to("direct:arrangeShipping")
  .compensation("direct:cancelOrder")
  .end();

from("direct:cancelOrder")
  .to("direct:releaseInventory")
  .to("direct:refundPayment");

SAGA는 최종적 일관성(eventual consistency)을 보장합니다. 즉각적인 일관성이 필요 없고 성능이 중요한 경우에 적합합니다.

zerg96

Share
Published by
zerg96

Recent Posts

[Apache Camel] 2025년 최신 트렌드 – AI 통합과 서버리스 Camel의 미래

2025년 Apache Camel의 최신 트렌드를 분석합니다. AI/LLM 통합 컴포넌트, 서버리스 배포, Camel K 진화, WebAssembly…

8시간 ago

[Camel in Action] 완결편 – Apache Camel 전체 여정 회고와 다음 단계

Camel in Action을 완독한 후 Apache Camel의 전체 그림을 다시 정리합니다. 핵심 철학, 학습 경로,…

8시간 ago

[Camel in Action] 실전편 – Camel 마이그레이션 가이드 2.x에서 4.x까지

Apache Camel 2.x에서 3.x, 4.x로 마이그레이션하는 단계별 가이드입니다. 주요 API 변경사항, 제거된 컴포넌트, 자동화 도구…

8시간 ago

[Camel in Action] 실전편 – Camel 라우트 디버깅 기법과 문제 해결 가이드

Apache Camel 라우트에서 발생하는 문제를 디버깅하고 해결하는 실전 기법을 설명합니다. 로그 분석, breakpoint 디버깅, Tracer,…

8시간 ago

[Camel in Action] 실전편 – Camel 도입 전 반드시 알아야 할 것들

Apache Camel을 프로젝트에 도입하기 전 알아야 할 핵심 사항을 정리합니다. 학습 곡선, 도입 비용, 적합한…

8시간 ago

[Camel in Action] 실전편 – Enterprise Integration Patterns 20가지 핵심 정리

엔터프라이즈 통합 패턴(EIP) 20가지를 Apache Camel 코드와 함께 한 번에 정리합니다. 메시징 채널, 메시지 라우팅,…

8시간 ago