Problem
Engineering context
A balance update without its movement record leaves inventory history inconsistent.
Solution boundary
Execute both changes in one transaction and rollback on failure.
Transactions
Updates a balance and records its movement atomically.
Problem
A balance update without its movement record leaves inventory history inconsistent.
Execute both changes in one transaction and rollback on failure.
START TRANSACTION;
UPDATE inventory_items
SET quantity = quantity - :quantity
WHERE id = :item_id
AND company_id = :company_id
AND quantity >= :quantity;
INSERT INTO stock_movements (item_id, company_id, quantity_delta)
VALUES (:item_id, :company_id, -:quantity);
COMMIT;
How it works
The guarded update prevents a negative quantity before the movement is recorded.
Security considerations
Bind parameters through the database driver; do not concatenate input.
Performance considerations
Index item and tenant keys and keep the transaction short.
Tradeoffs
Contention may require retry logic under high write concurrency.
Testing notes
Test insufficient stock, concurrency and rollback.
Limitations
Illustrative public-safe example; adapt the boundary and domain rules to the actual application.
Engineering evidence
Continue exploring
Coordinates a stock adjustment inside a database transaction while keeping HTTP concerns outside the domain operation.
Engineering insights
Double opt-in, no list selling, and unsubscribe anytime.
Your privacy, your choice
Basic page totals are counted without identifying you. If you accept analytics, anonymous session, time, scroll, device, browser and coarse location signals help reveal what is useful. Raw IP addresses are never stored.