
분산 시스템에서 데이터의 일관성과 비즈니스의 정합성을 보장하기 위해서 SAGA pattern을 주로 활용하곤 합니다. 이번 포스팅에서는 SAGA pattern이 무엇이고 어떻게 활용되는지 알아보겠습니다.
다른 트랜잭션의 결과에 따라 롤백이 필요한 경우에는 어떻게 해야할까?
(e.g 고객이 주문을 발생하여 주문 생성 -> 결제 요청 -> 잔액 부족 -> 생성된 주문 트랜잭션 롤백 필요.)
여기에서 나오는 개념이 바로 "보상 트랜잭션" 이다.

위 이미지는 사가 패턴이 적용된 사례이다.
한도 결과에 의해 한도 초과인 경우, 앞서 발생한 주문을 취소해야 한다. 이와 같이 이전 서비스의 로컬 트랜잭션이 작성한 변경 사항 (주문 생성)을 취소하는 트랜잭션을 보상 트랜잭션이라고 이해하자.
위와 같이, 하나의 큰 트랜잭션을 4개의 분리된 로컬 트랜잭션으로 비즈니스의 정합성을 보장할 수 있다.
데이터 일관성이 반드시 실시간으로 보장될 필요가 있을까?
주문 트랜잭션에서 주문자가 폭주한 경우를 생각해보자.
주문, 결제, 결제 결과 이메일 처리가 필요한 주문 트랜잭션을 순차적인 동시 일관성을 추구하는 경우 주문이 폭주하면 결제 처리가 지연되는 경우가 발생할 수 있다.
이러한 경우를 비즈니스 관점에서 보면 주문과 결제, 이메일 전송을 순차 처리하기 보단 무조건 먼저 주문을 많이 받아 놓는 것이 좋을 것이다.
모든 비즈니스의 데이터 일관성이 실시간으로 맞지 않더라도 어느 시점이 됐을 때 이를 만족해도 되는 경우가 있다. 이러한 개념을 결과적 일관성 (eventual consistency) 라고 한다.
결과적 일관성은 서비스의 고가용성을 극대화하는데, 사가패턴과 이벤트 메시지 기반 비동기 통신을 적용한 로직을 보며 이해할 수 있다.

가 주문이 생성되고 ‘가 주문됨’ 이벤트를 발행한다. 주문은 독립적 로컬 트랜잭션이기 때문에 끊임없이 받을 수 있다. 주문이 몰릴 경우 주문서비스만 확장하여 가용성을 높일 수 있다.
‘가 주문됨’ 이벤트는 메시지 브로커에 비동기로 전송된다.
결제 서비스는 발행된 ‘가 주문됨’ 이벤트를 확인하여 결제서비스는 자신의 대금결제 트랜잭션을 수행하고 ‘결제 처리됨’ 이벤트를 발행한다.
이메일 서비스는 ‘결제 처리됨’ 이벤트를 확인하여 주문결제완료 이메일을 사용자에게 발송한다.
주문 서비스는 ‘결제 처리됨’이벤트를 확인하여 가 주문 처리되었던 주문을 최종 승인한다. 그리고 ‘최종 주문 완료됨’이벤트를 발행한다.
이메일 서비스는 주문 서비스가 발행한 ‘최종 주문 완료됨’ 이벤트를 확인하여 최종 주문 완료됐다는 이메일을 사용자에게 발송한다.
각 서비스는 해당 작업 수행하다 오류가 발생하면 마찬가지로 ‘실패 이벤트’를 발행하여 다른 서비스가 비즈니스 정합성을 맞출 수 있도록 한다.
이때 별도로 메시지 큐에 쌓이는 이벤트들을 모니터링 서비스와 연계해 모니터링하고 추적하여 전체적인 비지니스 정합성 여부를 관리자가 확인하도록 한다.
이처럼 이벤트 기반 아키텍처와 메시지 브로커, 사가 패턴으로 비즈니스 정합성을 결과적으로 보장할 수 있고 가숑성을 극대화할 수 있습니다.