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.
Input:
Output:
Explanation: The retry for s1 does not subtract another four units. Confirmation changes lifecycle state without changing the existing inventory hold.
Input:
Output:
Explanation: The failed reservation for b stores nothing. Cancelling a restores its four units, allowing the retry for b to succeed.
0 <= initialStock <= 10^91 <= quantity <= 10^91 <= sagaId.length <= 40500 method calls are made per object.| Call | Returns |
|---|---|
| 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.

