Consultor Eletrônico



Kbase 20719: AS/400 Message CPF5027 and Record Contention
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   15/10/2008
Status: Verified

FACT(s) (Environment):

Progress/400 DataServer

SYMPTOM(s):

Notification message "CPF5027" is received when running application.

CAUSE:

The message indicates a deadlock. A deadlock situation can occur when two user sessions are repeatedly attempting to lock records that the other session has already locked.

As an example, consider the case when there are two users (User-A and User-B) and User-A executes the following code in a Progress session:

FIND FIRST table-a EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
PAUSE 15.
REPEAT:
FIND FIRST table-b EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
IF LOCKED table-b THEN NEXT.
LEAVE.
END.

At approximately the same time (to illustrate the problem, within the same 15 seconds), User-B runs the following code within his session:

FIND FIRST table-b EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
PAUSE 15.
REPEAT:
FIND FIRST table-a EXCLUSIVE-LOCK NO-WAIT NO-ERROR.
IF LOCKED table-a THEN NEXT.
LEAVE.
END.

After the "PAUSE 15" has executed, both user sessions have a record locked exclusively in table-a or table-b. When the repeat loop in either session tries to lock a record in the second table, it fails because the other user has the record already locked.

The repeat loop causes the session to make another attempt to lock the record. This attempt fails again. This deadlock situation exists until one user terminates his running process, freeing his session record locks. The other user session is now able to gain the lock it wants and complete its processing.

The deadlock problem exists on any deployment platform and, because of the syntax used, there is no indication of the contention other than the lack of process completion and high CPU usage. The same is true with the Progress/400 DataServer, with the exception that the AS/400 PROSERVER joblog contains the message CPF5027:

CPF5027 - Record <recno> in use by job
<jobid>/<username>/PROSERVER

There could be many of these messages in the joblog. It does not take long to create a joblog with thousands of pages consisting entirely of message CPF5027 reporting an attempt to lock a single record.

FIX:

Address the locking strategy used within the application. This could be done in several ways including the following:

1. Remove NO-ERROR on the FIND statements.

The existence of NO-WAIT on the FIND statements ensures that
the error condition is raised and that the user is informed.

2. Remove "NO-WAIT" on the FIND statements.

Since the record is being locked exclusively, a failure to
get the lock displays a message to the user that the record
is already locked.

3. Use the "ERROR-STATUS" system handle to programmatically handle
such record contention.

4. Reduce the code into two transactions, one per table.

5. If both tables have to be updated in the same transaction, ensure that both processes lock and update the tables in the same order.