메시지 추적과 중복 메시지 솎아 내기
소비자 신용카드를 승인하는 메시지 핸들러가 있다고 합시다. 주문별로 정확히 1회 신용카드를 승인해야 하겠죠. 이런 종류의 애플리케이션 로직은 호출될 때마다 영향을 미치므로 중복 메시지 때문에 같은 로직이 여러 번 실행되면 문제가 심각해집니다. 따라서 반드시 메시지 핸들러가 중복 메시지를 걸러 내서 멱등하게 동작하도록 만들어야 합니다.
컨슈머가 메시지 ID를 이용하여 메시지 처리 여부를 추적하면서 중복 메시지를 솎아 내면 간단히 해결됩니다. 이를테면 컨슈머가 소비하는 메시지 ID를 무조건 DB 테이블에 저장하면 되겠죠(그림 3-12).
▲ 그림 3-12 컨슈머는 처리된 메시지 ID를 DB 테이블에 기록해서 중복 메시지를 솎아 낸다. 이전에 메시지를 처리한 적이 있다면 PROCESSED_MESSAGES 테이블에 INSERT할 때 실패할 것이다
컨슈머는 메시지를 처리할 때 비즈니스 엔터티를 생성/수정하는 트랜잭션의 일부로 메시지 ID를 DB 테이블에 기록합니다. 그림 3-12의 컨슈머는 PROCESSED_MESSAGES라는 전용 테이블(dedicated table)에 메시지 ID가 포함된 로우를 삽입합니다. 중복된 메시지라면 INSERT 쿼리가 실패하고 조용히 무시되겠죠.
전용 테이블 대신 일반 애플리케이션 테이블에 메시지 ID를 기록하는 방법도 있습니다. 한 DB 트랜잭션으로 두 테이블을 업데이트하는 일이 불가능한, 트랜잭션 모델이 제한적인 NoSQL DB를 쓸 때 유용한 방법입니다(자세한 예제는 7장에서 설명합니다).