11. 크로스-샤드 구매 사가: 부분 실패 보상·멱등·내구 로그 부재 (C#)
난이도 최상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// [시나리오] 크로스-샤드 구매 사가 (서버-서버)
// 프리미엄 상점 구매는 서로 다른 서비스에 걸쳐 있다:
// - 지갑 서비스(샤드 A): 플레이어의 유료 재화를 차감한다.
// - 인벤토리 서비스(샤드 B): 구매한 아이템을 지급한다.
// 하나의 로컬 트랜잭션으로 두 서비스를 함께 커밋할 수 없으므로, 각 단계는
// 독립적인 원격 호출이다(각각 성공/실패/타임아웃할 수 있다).
//
// [요구사항]
// - 돈을 냈으면 아이템을 받아야 하고, 아이템을 못 주면 돈을 돌려줘야 한다(원자성 효과).
// - 재시도나 프로세스 재기동이 있어도 이중 차감·이중 지급이 없어야 한다.
//
// [과제] PurchaseSaga.BuyItem 을 검토하고, 지급 단계가 실패/타임아웃하거나
// 중간에 프로세스가 죽는 경우 무엇이 남는지, 그리고 재시도하면 어떻게
// 되는지 원인과 수정안을 제시하라. 표시된 (A)(B) 지점에 주목하라.
using System;
interface IWalletService { void Debit(int playerId, long amount); void Refund(int playerId, long amount); }
interface IInventoryService { void Grant(int playerId, string itemId); }
class PurchaseSaga
{
private readonly IWalletService _wallet; // 샤드 A
private readonly IInventoryService _inventory; // 샤드 B
public PurchaseSaga(IWalletService w, IInventoryService i) { _wallet = w; _inventory = i; }
public void BuyItem(int playerId, string itemId, long price)
{
// (A)
_wallet.Debit(playerId, price);
// (B)
_inventory.Grant(playerId, itemId);
}
} 결함 코드 · C++
// [시나리오] 크로스-샤드 구매 사가 (서버-서버)
// 프리미엄 상점 구매는 서로 다른 서비스에 걸쳐 있다:
// - 지갑 서비스(샤드 A): 플레이어의 유료 재화를 차감한다.
// - 인벤토리 서비스(샤드 B): 구매한 아이템을 지급한다.
// 하나의 로컬 트랜잭션으로 두 서비스를 함께 커밋할 수 없으므로, 각 단계는
// 독립적인 원격 호출이다(각각 성공/실패/타임아웃할 수 있다).
//
// [요구사항]
// - 돈을 냈으면 아이템을 받아야 하고, 아이템을 못 주면 돈을 돌려줘야 한다(원자성 효과).
// - 재시도나 프로세스 재기동이 있어도 이중 차감·이중 지급이 없어야 한다.
//
// [과제] PurchaseSaga::buyItem 을 검토하고, 지급 단계가 실패/타임아웃하거나
// 중간에 프로세스가 죽는 경우 무엇이 남는지, 그리고 재시도하면 어떻게
// 되는지 원인과 수정안을 제시하라. 표시된 (A)(B) 지점에 주목하라.
#include <string>
#include <cstdint>
#include <stdexcept>
struct DownstreamError : std::runtime_error { using std::runtime_error::runtime_error; };
class WalletService { // 샤드 A
public:
void debit(int playerId, int64_t amount); // 실패 시 DownstreamError
void refund(int playerId, int64_t amount);
};
class InventoryService { // 샤드 B
public:
void grant(int playerId, const std::string& itemId); // 실패 시 DownstreamError
};
class PurchaseSaga {
WalletService& wallet_; // 샤드 A
InventoryService& inventory_; // 샤드 B
public:
PurchaseSaga(WalletService& w, InventoryService& i) : wallet_(w), inventory_(i) {}
void buyItem(int playerId, const std::string& itemId, int64_t price) {
// (A)
wallet_.debit(playerId, price);
// (B)
inventory_.grant(playerId, itemId);
}
}; 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.