Subject Deadlock error on stored procedure
Author Don Schoeman
I get the following error when running a simple stored proc:

Exception = ISC ERROR CODE:335544336

ISC ERROR MESSAGE:
deadlock
update conflicts with concurrent update

This error seems to occure only after running the following stored proc and
then running another stored proc accessing the same dataset:

CREATE PROCEDURE FINISH_CASH_TRANS
(
"P_TERM_NO" INTEGER,
"P_CUST_ID" INTEGER,
"P_VAT" FLOAT,
"P_VAT_TOTAL" NUMERIC(8,2),
"P_GND_TOTAL" NUMERIC(8,2)
)
AS
DECLARE VARIABLE v_invoice_no INTEGER;
DECLARE VARIABLE v_term_no INTEGER;
DECLARE VARIABLE v_item_no INTEGER;
DECLARE VARIABLE v_item_id INTEGER;
DECLARE VARIABLE v_price INTEGER;
DECLARE VARIABLE v_quantity INTEGER;
DECLARE VARIABLE v_item_state INTEGER;
BEGIN
/*
* First we retrieve the new invoice no. and then create a new cash
transaction
*/
v_invoice_no = GEN_ID(CASH_INV_NO_GEN, 1);
INSERT INTO CASH_SALES
(INVOICE_NO, CUST_ID, TRANS_DATE, TRANS_TIME, TERM_NO, VAT, VAT_TOTAL,
GND_TOTAL)
VALUES
(:v_invoice_no, :p_cust_id, 'NOW', 'NOW', :p_term_no, :p_vat,
:p_vat_total, :p_gnd_total);

/*
* Now loop through all the items added in this transaction and subtract
each of
* them from the STOCK quantity.
*/
FOR SELECT TERM_NO, ITEM_NO, ITEM_ID, PRICE
FROM TMP_CASH
WHERE TERM_NO = :p_term_no
INTO :v_term_no, :v_item_no, :v_item_id, :v_price
DO BEGIN

/* Get the current stock quantity for this item */
FOR SELECT QUANTITY, STATE_ID
FROM STOCK
WHERE ITEM_ID = :v_item_id
INTO :v_quantity, :v_item_state
DO

/* Subtract 1 from the stock quantity of this item */
v_quantity = v_quantity - 1;
IF (v_quantity <= 0) THEN
BEGIN
v_quantity = 0;
v_item_state = 2; /* Out of stock */
END

UPDATE STOCK
SET QUANTITY = :v_quantity, STATE_ID = :v_item_state
WHERE ITEM_ID = :v_item_id;

/* Add this item to the cash sales record */
INSERT INTO CASH_ITEMS
(INVOICE_NO, ITEM_NO, ITEM_ID, PRICE)
VALUES
(:v_invoice_no, :v_item_no, :v_item_id, :v_price);
END

/* Finally delete all temporary items from the TMP_CASH table. */
DELETE FROM TMP_CASH
WHERE TERM_NO = :v_term_no;
SUSPEND;
END
^

Best Regards,
Don Schoeman