MainframeSupports
tip week 21/2010:

When a SQL statement is executed it returns a SQLCODE in SQLCA. The SQLCODE tells you something about how the execution ended. Either it was successfully executed (SQLCODE = 0) or something went wrong (SQLCODE <> 0). Based on the SQLCODE you decide what to do and code it into your SQL error handling.

If your SQL statement returns SQLCODE -911 (deadlock or timeout) DB2 has already decided to perform a ROLLBACK. It is the only SQLCODE having this side effect and therefore it is extremely important to react on SQLCODE -911 and the most sane reaction is to stop program execution without performing any DB2 updates. If a SQLCODE -911 is not treated reasonably it will most likely cause data inconsistency.

During the last ten years there has been a tendency to split applications into smaller units. Splitting of applications is a consequence of component based methods and Service Oriented Architecture (SOA). One of the results of atomising applications is that it becomes extremely difficult to trace where problems arise and to communicate the problem up through the hierarchy of units. Therefore it might happen that a SQLCODE -911 is not treated correctly.

If you are in a situation where a program or application is hit by undetected SQLCODE -911 during execution and causing inconsistent data you can try the following in order to circumvent the error. Perform a SQL INSERT as the first thing in your unit of work. Just before you issue a COMMIT you check whether your INSERTed row is still present by performing a DELETE of the row. If the row is still there everything is OK, but if it has disappeared then a ROLLBACK has been performed. It may be coded like this:

...
SET :myTime = CURRENT TIMESTAMP
INSERT INTO MYROLLBACKCHECKER (MYTIME) VALUES(:myTime)
...
perform the rest of the unit of work
...
DELETE FROM MYROLLBACKCHECKER WHERE MYTIME = :myTime
IF SQLCODE = 0
  COMMIT
ELSE
  ROLLBACK
  terminate program
END-IF
...

An important detail is that the table MYROLLBACKCHECKER must have a unique index on MYTIME and that the DELETE uses this index when the row is about to be deleted. Otherwise you may create new SQLCODE -911 problems. A smart detail about the above solution is that if the program or application is designed for restart then you can restart it automatically if the DELETE fails with a SQLCODE of 100, because then you know that your unit of work has been rolled back to the last executed COMMIT. In this case you must of course remember to issue a ROLLBACK otherwise the data inconsistency will persist. As you may have noticed by now this tip does not help you to detect the error, but it effectively prevents inconsistent data caused by a undetected SQLCODE -911.

Previous tip in english        Sidste danske tip        Tip list