관련 링크


1. 문제

1.1 상황

재고를 예약한 이후, 서버 장애 등의 이유로 예약된 재고 정보가 소실되는 경우, 실제 재고는 있는데 DB 상에는 없는 경우가 발생한다.

1.2 발생한 문제

현재 결제 처리 흐름은 다음과 같다.

// 결제 처리 로직

try {
		reservedLines = reserveOrderStocks(order); // 재고 예약
		
    tossPaymentClient.confirm(...); // 결제 진행

    // 성공
    payment.complete();
    order.complete();
} catch (...) {

    // 실패
    restoreReservedStocks(reservedLines); // 재고 복구
}

하지만 서버 장애로 인해 재고 예약 이후 서버 실행이 중단된다면, catch 문이 실행되지 못하여 재고 손실이 발생하게 된다.

try {
		reservedLines = reserveOrderStocks(order); // 재고 예약
		
		// 💥 예상치 못한 이유로 로직 중단
		
    tossPaymentClient.confirm(...); // 결제 진행

    // 성공
    payment.complete();
    order.complete();
} catch (...) {

    // 실패
    restoreReservedStocks(reservedLines); // 재고 복구
}

이로 인해 다음과 같은 영향이 발생한다.

따라서 위 문제를 해결할 필요가 있었다.


2. 문제 구체화 및 해결방안