Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions target-service/files/welcome.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hello from storage
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,26 @@ public InventoryItem save(InventoryItem item) {
public int stock(String sku) {
return findBySku(sku).stock();
}

/**
* Atomically deducts stock for a given SKU.
* Uses ConcurrentHashMap.compute to ensure read-check-write atomicity.
* @throws IllegalArgumentException if SKU not found or insufficient stock
*/
public InventoryItem deductStock(String sku, int quantity) {
if (quantity <= 0) {
throw new IllegalArgumentException("quantity must be positive, but got: " + quantity);
}
return store.compute(sku, (key, item) -> {
if (item == null) {
throw new IllegalArgumentException("SKU not found: " + sku);
}
if (item.stock() < quantity) {
throw new IllegalArgumentException(
"insufficient stock for " + sku + ": have " + item.stock() + ", need " + quantity);
}
return new InventoryItem(item.sku(), item.name(),
item.stock() - quantity, item.reserved() + quantity);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,10 @@ public InventoryService(InventoryRepository repository) {
}

/**
* Deducts stock for a given SKU.
* BUG: No synchronization — concurrent calls can over-sell inventory.
* Deducts stock for a given SKU using atomic operation.
*/
public InventoryItem deduct(String sku, int quantity) {
if (quantity <= 0) {
throw new IllegalArgumentException("quantity must be positive, but got: " + quantity);
}
InventoryItem item = repository.findBySku(sku);
if (item.stock() < quantity) {
throw new IllegalArgumentException(
"insufficient stock for " + sku + ": have " + item.stock() + ", need " + quantity);
}
InventoryItem updated = new InventoryItem(item.sku(), item.name(),
item.stock() - quantity, item.reserved() + quantity);
return repository.save(updated);
return repository.deductStock(sku, quantity);
}

public InventoryItem getStock(String sku) {
Expand Down