재고 연동
작성: seokjin8678상품을 게시하고, 이후 쇼핑몰에서 상품이 판매되면, 해당 쇼핑몰을 제외한 다른 쇼핑몰에 품절 상태로 변경해야 중복 주문이 발생하지 않습니다.
해당 기능은 외부 쇼핑몰에서 웹훅을 통해 구현되어 있습니다.
기본적으로 쇼핑몰이 중복 구매 동시성 문제를 해결했다고 가정하며 구현되었습니다.
중복 구매 동시성 문제는 해결했으나, 웹훅이 exactly-once가 보장되지 않는 경우가 있을 수 있기에, 같은 쇼핑몰에서 온 중복 주문 건은 무시됩니다.
하지만 다른 쇼핑몰에서 서로 다른 고객이 주문하는 것은 동시성 문제가 그대로 발생하며, 이 때문에 중복 주문이 발생할 수 있습니다.
서로 다른 쇼핑몰들에 대해 상호 배제를 구현하여 중복 주문을 막는 것은 불가능하므로, 가장 먼저 웹훅을 요청한 쇼핑몰의 주문만 인정합니다. 그 이후에 인입된 주문은 중복으로 판단하여 취소를 유도할 수 있습니다.
2025.11.29 기준 서버에 에러 로그만 남기고, 셀러에게 알림을 전송하지 않습니다. 따라서 이후 셀러에게 알림을 전송하는 기능이 필요합니다.
주문 취소의 경우, 주문과 다르게 중복 주문 취소가 생길 일은 논리적으로 존재할 수 없습니다.
하지만 셀러가 중복 주문 상태를 인지하고 임의로 주문을 취소하면 논리적 오류가 발생할 수 있습니다. 정상 주문이 완료된 상태에서 셀러가 다른 쇼핑몰의 중복 주문을 취소하면, 재고가 의도치 않게 회복되어 모든 쇼핑몰에 다시 재고가 동기화될 수 있기 때문입니다.
따라서, 중복 주문이 발생하면 해당 상품은 재고 회복을 하지 못하게 만들어야 위와 같은 논리적인 오류가 발생하지 않습니다.
이는 PublishedProduct의 anomaly 필드를 통해 제어합니다.
PublishedProduct가 anomaly 상태이면, 외부 쇼핑몰에 재고 연동을 하지 않습니다.
또한 중복 주문/재고 회복 요청의 경우, 또 다른 중복 요청이 발생하지 않도록 해당 쇼핑몰의 상품을 매진 상태로 변경합니다.
PublishedProductSaleHistory
Section titled “PublishedProductSaleHistory”외부 쇼핑몰에서 판매/구매 취소 상태를 기록과 중복 주문 제어를 위한 엔티티입니다.
상태는 INITIAL, SOLD, RESTOCK 3가지가 있으며, INITIAL 상태는 상품이 게시된 시점에 생성되는데, 해당 행은 동시성 문제를 막을 때
사용되는 FOR UPDATE 쿼리에서 next key lock을 방지하기 위해 생성하는 용도입니다.
중복된 주문/재고 회복 요청이 인입되면, 먼저 PublishedProductSaleHistory에 새로운 기록을 INSERT합니다. 그 다음, 새로 생성된 기록의 식별자보다
작은 값을 가진 이전 기록을 조회하여 다른 요청이 먼저 처리되었는지 확인하고, 이를 통해 중복 여부를 판단합니다.
REPEATABLE READ격리 수준에서는FOR UPDATE쿼리 실행 시 조회된 행이 없으면 next-key lock이 발생할 수 있습니다. 하지만INITIAL상태의 행이 항상 존재하여 조회되므로, next-key lock을 방지할 수 있습니다.