Hi all

I am designing an inventory application, and I want to ensure that the stock 
level of any item cannot go negative.

Instead of maintaining a running balance per item, I store the original 
quantities received in one table (call it ‘inv_rec’), and any amounts removed 
in another table (call it ‘inv_alloc’).

CREATE TABLE inv_rec
    (row_id SERIAL PRIMARY KEY,
    product_id INT REFERENCES inv_products,
    qty INT);

CREATE TABLE inv_alloc
    (row_id SERIAL PRIMARY KEY,
    rec_id INT REFERENCES inv_rec,
    qty INT);

To get the balance of a particular item -

SELECT SUM(
    a.qty + COALESCE(
      (SELECT SUM(b.qty) FROM inv_alloc b
      WHERE b.rec_id = a.row_id), 0))
FROM inv_rec a
WHERE a.product_id = 99;

To remove a quantity from a particular item -

INSERT INTO inv_alloc (rec_id, qty)
  VALUES (23, -1);

I want the application to check that there is sufficient quantity before 
attempting to execute the INSERT command.

If ok, it will look for a suitable row in ‘inv_rec’ to allocate against.

The danger of course is that, in a multi-user system, another user might have 
removed an additional quantity from the same item in between the SELECT and the 
INSERT.

I *think* that the solution is to BEGIN the transaction, then perform SELECT 
... WITH UPDATE, then proceed with INSERT and COMMIT if ok, else ROLLBACK.

Is this the correct approach, or am I missing something?

Thanks

Frank Millman

Reply via email to