핵심 목표
대용량 선착순 트래픽 상황에서도 데이터 정합성이 지켜져야 하며, 최대한의 재고 회전율을 보장해야 한다.
PENDING 확인)PENDING → PAYMENT_IN_PROGRESS)paymentClient.approve)rollbackToPending수행 (PAYMENT_IN_PROGRESS → PENDING)PAYMENT_IN_PROGRESS → PAID)Payment) 저장.PAYMENT_IN_PROGRESS 상태를 추가했는가?기존 세 가지 OrderStatus
PENDING, CANCELLED, PAID에서 왜PENDING→PAID로 가지 않고PAYMENT_IN_PROGRESS를 추가해주었을까?
Why
중복 결제(따닥) 위험 방지 : 낙관적 락 역할
상태 변경 그 자체를
논리적인 락으로 사용하여 동시성 문제를 데이터베이스 레벨에서 해결한다.
따닥 누른 상황IN_PROGRESS 없이 PENDING만 존재 할 경우
PENDING 상태를 확인하고 PG사로 결제 요청 전송.IN_PROGRESS가 있을 경우
update...set status='PAYMENT_IN_PROGRESS' where status='PENDING'
→ 성공 → 결제 진행.update...set status='PAYMENT_IN_PROGRESS' where status='PENDING'
→ 실패 (이미 A가 바꿔놔서 PENDING이 아님).명확한 의도와 구분
비즈니스 관점에서 사용자의 의도를 파악하는 데에 도움이 되고, 각각 두 상태가 갖는 의미를 다르게 해석하여, 이에 맞는 만료 시간 및 그에 따른 스케줄링 정책 등을 비즈니스 적으로 다르게 가져갈 수 있다.
PENDING → 만료 시간 5분 (공격적 회수)
IN_PROGRESS → 만료 시간 15분 (안전한 회수)
위에서 낙관적 락 역할로서 조건부 update 문을 명시적으로 사용했다.
낙관적 락 역할이면 JPA 에 이미 @Version 을 사용할 수 있을텐데 왜 사용하지 않았을까?
Why