(MSA 분산 트랜잭션) 주문-재고관리 어떻게 하지?
MSA 분산 트랜잭션 MSA distributed transaction
일반적으로 온라인 커머스 서비스를 하고, 재고가 존재하는 상품을 판매 한다면
주문 - 재고차감- 결제 등의 프로세스가 필요할 것이다.
위 프로세스는 일관성을 유지해야한다.
만약 결제에서 오류가 발생했다면 재고차감, 주문까지 rollback이 되어야 일관성이 유지된다.
모놀리식으로 구성된 서비스라면 위 프로세스를 한트랜잭션으로 묶어버리던지
하는 방법이 있겠지만 MSA 환경에서는 주문, 재고관리, 결제 서비스가 나뉘고 DB도 따로 관리 될것이라
한 트랜잭션으로 처리 하는 것은 기술적으로 어렵고, 처리한다고 해도 한 트랜잭션이 너무 길어져 다른 방법이 필요하다.
MSA에서 서비스간 일관성을 유지하는 방법 중 하나로 TTC가 알려져있다.
TTC : Try-Confirm-Cancel
REST 기반으로 간단하게 TTC를 구현하는 예시
기존 주문 프로세스
1. 클라이언트 주문요청 -> OrderService
2. OrderService 재고 차감 요청 -> StockService
3. OrderService 결제 요청 -> PaymentService
4. OrderService 주문 저장 -> Order DB
2 - 3 과정을 try 만 하도록 하고,
마지막에 confirm 과정을 거쳐 전체 프로세스가 완료되도록 할 수 있다.
StockService, PaymentService는 try 요청을 받은 후 confirm이 호출 된 시점에 실제 작업을 수행한다.
TTC가 적용된 프로세스
1. 클라이언트 주문요청 -> OrderService
2. OrderService 재고 차감 Try -> StockService ( 재고차감 try에 대한 데이터 저장 및 confirm에 쓰일 uri 응답)
3. OrderService 결제 Try -> PaymentService ( 결제 try에 대한 데이터 저장 및 confirm에 쓰일 uri 응답)
4. OrderService 재고 차감 Confirm (응답받은 uri로 요청) -> StockService (실제 재고차감 수행 및 try 데이터 상태 처리완료로 변경)
5. OrderService 결제 Confirm (응답받은 uri로 요청) -> PaymentService (실제 결제 수행 try 데이터 상태 처리완료로 변경)
6. OrderService 주문 저장 -> Order DB
( 6단계 성공 이후 전체 confirm으로 구현할 수도 있어보임)
기존에 try-confirm 과정이 추가된다.
이 과정을 추가함으로써 전체 프로세스 진행 중, 중간에 실패한 경우 confirm을 실행하지 않음으로써 일관성을 유지할수 있다.
실패한 경우는 요청했던 try 데이터에 대한 데이터에 대한 상태를 바꾸어 리소스점유를 해제 해주어야한다.
TTC에서는 Cancel 혹은 Timeout을 사용하여 리소스 점유를 해제한다.
한계
1. confirm 중에 오류가 난다면? -> 결과적 일관성 적용. 큐잉 등을 통해 요청을 성공할때까지 다시 처리
2. 재고 확인에서 (실제 재고 + 재고차감요청 데이터)로 재고를 계산하는데
재고차감 요청데이터 상태가 confirm인것은 +, cancel 인것은 - 로 한다.
하지만 아직 상태가 없는것 (confirm 전)은 어떻게 처리할것인가? 고민중..