AlgoMaster Logo
AlgoMasterBuild an Idempotent Saga Reservation Servicehard

Build an Idempotent Saga Reservation Service

hard

A saga compensation is a new business operation, not a database rollback. That operation must remain correct when commands are retried because a reply was lost or an orchestrator restarted.

Design an InventoryReservationService class:

  • InventoryReservationService(int initialStock) stores the available inventory.
  • String reserve(String sagaId, int quantity) attempts to hold inventory for one saga.
  • String confirm(String sagaId) confirms a held reservation.
  • String cancel(String sagaId) compensates a held or confirmed reservation.
  • int available() returns the current available stock.

Each successful reservation has one of three states: HELD, CONFIRMED, or CANCELLED.

For an unknown sagaId, reserve returns "INSUFFICIENT_STOCK" without creating state when stock is too low. Otherwise, it subtracts quantity, stores a held reservation, and returns "RESERVED".

Commands for a known saga are idempotent:

  • reserve returns "RESERVED", "CONFIRMED", or "CANCELLED" according to the stored state and never changes stock again.
  • confirm changes HELD to CONFIRMED; it returns "CONFIRMED" for held or already confirmed reservations, "CANCELLED" for a cancelled reservation, and "NOT_FOUND" for an unknown saga.
  • cancel changes HELD or CONFIRMED to CANCELLED and restores the stored quantity exactly once. It returns "CANCELLED" for an already cancelled reservation and "NOT_FOUND" for an unknown saga.

Every repeated reserve for a known saga uses the same quantity as its first successful reservation.

Example 1:

Input:

Output:

Explanation: The retry for s1 does not subtract another four units. Confirmation changes lifecycle state without changing the existing inventory hold.

Example 2:

Input:

Output:

Explanation: The failed reservation for b stores nothing. Cancelling a restores its four units, allowing the retry for b to succeed.

Constraints

  • 0 <= initialStock <= 10^9
  • 1 <= quantity <= 10^9
  • 1 <= sagaId.length <= 40
  • Every retry of a successful saga reservation supplies its original quantity.
  • At most 500 method calls are made per object.
Hints

Loading...
CallReturns
new InventoryReservationService(10)null
reserve("s1", 4)"RESERVED"
reserve("s1", 4)"RESERVED"
available()6
confirm("s1")"CONFIRMED"
available()6

The duplicate reserve is idempotent and confirm changes only the reservation state, so stock is subtracted exactly once.

Run checks these cases. Submit also runs a larger hidden set.