I am trying to understand the unit of work and locking behavior of a Db2 for i (ver 7.4) SQL procedure created with SET OPTION COMMIT=*CHG.
Minimal reproducible example:
CREATE TABLE T_TEST_COMMIT (
ID INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
SRC VARCHAR(10) NOT NULL
);
CREATE OR REPLACE PROCEDURE P_TEST_CHG()
LANGUAGE SQL
MODIFIES SQL DATA
SET OPTION COMMIT = *CHG
BEGIN
INSERT INTO T_TEST_COMMIT (SRC)
VALUES ('CHG');
END;
The table has to be journaled to run the test.
Test:
CALL P_TEST_CHG();
DELETE FROM T_TEST_COMMIT;
The DELETE can fail with:
SQLSTATE 57033
SQL0913: Row or object T_TEST_COMMIT type *FILE in use
If I issue COMMIT or ROLLBACK after the procedure call, the lock is released (tested via Client Access)
Using QSYS2.OBJECT_LOCK_INFO, after the CALL and before COMMIT / ROLLBACK, I can see an UPDATE lock with LOCK_STATUS = HELD and LOCK_SCOPE = JOB on the inserted row.
My understanding is that P_TEST_CHG participates in the active unit of work / commitment control context of the caller, because the caller's ROLLBACK does roll back the insert.
But if that is correct, why can a subsequent DELETE or UPDATE from the same session/job fail with SQL0913 before COMMIT or ROLLBACK?
For example, this can also fail before ending the unit of work:
UPDATE T_TEST_COMMIT
SET SRC = 'X';
The practical issue is this: if a stored procedure modifies or prepares rows under COMMIT=*CHG, it looks like the caller cannot safely continue working on those same rows before ending the unit of work.
So my questions are:
- What is the correct Db2 for i model here?
- Is this expected behavior for SQL procedures using
SET OPTION COMMIT=*CHG? - Is there a recommended pattern or best practice for this kind of design?
- Are options such as
COMMIT ON RETURN,AUTONOMOUS,BEGIN ATOMIC, or statement-level clauses relevant here, or is the correct solution simply to avoid this pattern?
I have not been able to find a clear explanation in the Db2 for i SQL Reference, especially regarding the interaction between procedure-level SET OPTION COMMIT=*CHG, unit of work boundaries, and locks held after the procedure returns.