HLI: Record locking conflicts

From m204wiki
Jump to navigation Jump to search

Overview

This topic describes for the HLI programmer a typical locking conflict and provides an example of how to handle conflicts in a host language application. Refer to the guidelines for avoiding conflicts when you are coding your host language program.

When a record locking conflict occurs

If Model 204 cannot lock a record, a locking conflict occurs. Record locking conflicts can occur when multiple users try concurrently to access the same records and attempt overlapping updating operations.

A conflict arises when one or more users are reading a file (in SHR mode) and another user attempts to update the file (enqueuing in EXC mode) or when two or more users attempt to perform file maintenance (each requiring EXC mode access) on the same records retrieved from a file.

For update operations from a host language application, locking guarantees an HLI thread exclusive control of a resource until the thread completes update processing on the resource. Conflicting requests are automatically delayed until exclusive control is released.

Model 204 locks at different levels

Model 204 resolves internal enqueuing conflicts by locking at the following levels:

  • Files or groups
  • Sets of records
  • Single records
  • Arbitrary resources

For more information about record locking, see HLI: Find criteria for Model 204.

Example of record locking conflict

In this example, a SOUL request and an IFAM2 host language application attempt to access the same Model 204 record at the same time. Because the IFAM2 application requires an exclusive (EXC) lock, this situation causes a record locking conflict.

IFAM2 application requires an EXEC lock

Events occur in the following order:

  1. The SOUL request begins processing and finds all the records in the CARS file that were made in 1991 and starts to print a report. (The procedure enqueues the found records in SHR mode.)
  2. Then the host language application begins processing and finds all the FORD records in the CARS file, including some of the 1991 records selected by the SOUL request. The application then attempts an updating function that requires an EXC lock as it processes each record. However, the program cannot gain EXC access to any of the 1991 records.

The following figure illustrates the record locking conflict involving the SOUL procedure and the host language application.

Example of record locking conflict

SOUL request opens CARS with read-only privileges

The SOUL request begins processing first and opens the CARS file with read-only privileges (password is READS), selects the FORD records, and prints the information found in each record.

The SOUL request includes the following statements:

OPEN CARS READS BEGIN 1 FD MAKE=FORD YEAR=1991 2 FR 1 PRINT ALL INFORMATION END CLOSE CARS

Note: The records in the found set remain locked in SHR mode while they are being printed by the for loop.

IFAM2 application attempts to update CARS

The HLI IFAM2 batch application begins processing next and starts a multiple cursor IFSTRT thread, which allows update processing. The program opens the CARS file with update privileges (password is UPDATES) and selects the FORD records (using IFFAC).

The host language application starts a processing loop that performs the following functions:

  • Fetches (IFFTCH) each record in the found set.
  • Calls IFUPDT to update the record, changing the COLOR field to TAN.
  • Writes an output record to a user-specified report file.
  • Displays record counts.

However, as soon as the host language program attempts to perform the updating function on the first 1991 record in the found set, it enqueues on the record in EXC mode, as shown in Example of record locking conflict. Model 204 returns a completion code (RETCODE) of 3, which indicates that the required EXC lock on the record could not be obtained.

The excerpt from a COBOL host language program, in the section Sample host language error processing, updates the FORD records.

Resolution of the locking conflict

The host language application shown in Example of record locking conflict cannot access the 1991 records (which are locked in SHR mode by the SOUL procedure) until the SOUL request finishes processing or explicitly releases the records.

When the SHR lock has been released, the host language application can access the record in EXC mode and update records with IFUPDT.

Handling record locking conflicts

Specifying an action when a record locking conflict occurs

Model 204 allows the user to specify the action to be taken if, after an initial record locking attempt and subsequent wait, an effort to lock a set of records is still unsuccessful.

In SOUL, two special forms of ON units, the ON RECORD LOCKING CONFLICT and ON FIND CONFLICT, can be invoked to specify the action to be taken for a record locking conflict. A SOUL PAUSE statement can be used to cause the request to wait a specified time and then to retry the statement that caused the evaluation of the ON unit.

In your host language program, you can use the IFERLC call to help determine the cause of the record locking conflict and to specify an action to be taken.

Sample host language error processing

The following COBOL program excerpts show error processing in a host language program using an ERROR-RTN subroutine.

The program tests the Model 204 completion return code (RETCODE) after each HLI call. In this example, if the return code is not equal to zero, the program transfers control to ERROR-RTN and stops processing.

For a return code of 3, the program displays a record locking conflict message. For all nonzero return codes, the program displays an error message with the name of the HLI function call and the return code value. The error routine also calls IFGERR and displays the text of the Model 204 error message.

DATA DIVISION. FILE SECTION. FD UPDATE-REPORT LABEL RECORDS ARE STANDARD BLOCK CONTAINS 0 RECORDS DATA RECORD IS CAR-REC-OUT. 01 CAR-REC-OUT. 05 CAR-MAKE-OUT PIC X(5). 05 FILLER PIC X(10). 05 CAR-MODEL-OUT PIC X(5). 05 FILLER PIC X(10). 05 CAR-YEAR-OUT PIC X(2). 05 FILLER PIC X(10). 05 CAR-COLOR-OUT PIC X(3). WORKING-STORAGE SECTION. 01 M204-CALL-ARGS. 05 RETCODE PIC 9(5) COMP SYNC. 05 DIR PIC 9(5) COMP SYNC VALUE "1". 01 M204-ERROR. 05 M204-CALL-ERROR PIC X(8) VALUE SPACES. 05 M204-RETCODE-ERROR PIC 9(5) VALUE ZERO. 05 M204-MSG-ERROR PIC X(80) VALUE SPACES. 01 WK-VARS. 05 WK-COLOR PIC X(3) VALUE "TAN". 05 FIND-TOT PIC 9(5) VALUE ZERO. 05 UPDATE-TOT PIC 9(5) VALUE ZERO. 01 START-THREAD. 05 LANG-IND PIC 9(5) COMP SYNC. 05 LOGIN PIC X(12) VALUE "CARSUSER;UPDATES;". 05 THRD-TYPE PIC 9(5) VALUE "2" COMP SYNC. 05 THRD-NO PIC 9(5) COMP SYNC. 01 FILE-INFO. 05 FILE-NAME PIC X(10) VALUE "CARS;". 05 PASSWORD PIC X(6) VALUE "UPDATES;". 01 FIND-SPEC. 05 FDSPEC PIC X(10) VALUE "MAKE=FORD;". 05 COUNT PIC 9(5) COMP SYNC. 05 FDNAME PIC X(7) VALUE "FDNAME;". 05 END-CALL PIC X(4) VALUE "END;". 01 CURSOR-PARMS. 05 CURSPEC PIC X(10) VALUE "IN FDNAME;". 05 CURNAME PIC X(7) VALUE "CRNAME;". 01 WORK-REC. 05 MAKE PIC X(5) VALUE SPACES. 05 MODEL PIC X(5) VALUE SPACES. 05 YEAR PIC X(2) VALUE SPACES. 05 COLOR PIC X(3) VALUE SPACES. 01 CALL-ARGS. 05 RETCODE PIC 9(5) COMP SYNC. 05 RECNUM PIC X(11). 05 USERNUM PIC X(5). 05 FILENAME PIC X(8). 01 DATA-SPEC PIC X(49) VALUE "EDIT(MAKE,MODEL,YEAR,COLOR)(A(5),A(5),A(2),A(3));". . . . PROCEDURE DIVISION. . . . * START A MULTIPLE CURSOR THREAD * CALL "IFSTRT" USING RETCODE,START-THREAD. IF RETCODE IS NOT EQUAL TO ZERO THEN MOVE "IFSTRT " TO M204-CALL-ERROR GO TO ERROR-RTN. * * OPEN CARS WITH UPDATE PRIVILEGES * CALL "IFOPEN" USING RETCODE,FILE-INFO. IF RETCODE IS NOT EQUAL TO ZERO THEN MOVE "IFOPEN " TO M204-CALL-ERROR GO TO ERROR-RTN. * * FIND AND COUNT FORD RECORDS * CALL "IFFAC" USING RETCODE,FDSPEC,COUNT,FDNAME,END-CALL. IF RETCODE IS NOT EQUAL TO ZERO THEN MOVE "IFFAC " TO M204-CALL-ERROR GO TO ERROR-RTN * ELSE * UPDATE AND WRITE FORD RECORDS * MOVE COUNT TO FIND-TOT DISPLAY "TOTAL RECORDS FOUND IS " FIND-TOT CALL "IFOCUR" USING RETCODE,CURSPEC,CURNAME MOVE "IFOCUR " TO M204-CALL-ERROR PERFORM UPDATE-AND-WRITE UNTIL RETCODE IS NOT EQUAL TO ZERO OR FIND-TOT IS EQUAL TO ZERO. IF RETCODE IS NOT EQUAL TO ZERO THEN GO TO ERROR-RTN ELSE * * PRINT UPDATE TOTAL * DISPLAY "TOTAL RECORD UPDATED IS " UPDATE-TOT CALL "IFCCUR" USING RETCODE,CURNAME IF RETCODE IS NOT EQUAL TO ZERO THEN MOVE "IFCCUR " TO M204-CALL-ERROR GO TO ERROR-RTN. * GO TO END-RTN. * * * SUBROUTINE TO PROCESS FORD RECORDS * UPDATE-AND-WRITE. MOVE "IFFTCH " TO M204-CALL-ERROR. CALL "IFFTCH" USING RETCODE,WORK-REC,DIR,CURNAME,DATA-SPEC. PERFORM UPDATE-COLOR. PERFORM WRITE-REC. MOVE SPACES TO WORK-REC. SUBTRACT 1 FROM FIND-TOT. * * SUBROUTINE TO CHANGE COLOR TO TAN AND UPDATE FILE * UPDATE-COLOR. MOVE WK-COLOR TO COLOR. MOVE "IFUPDT " TO M204-CALL-ERROR. CALL "IFUPDT" USING RETCODE,WORK-REC,CURNAME,DATA-SPEC. IF RETCODE IS EQUAL TO 3 THEN GO TO ERROR-RTN. MOVE "IFCMMT " TO M204-CALL-ERROR. CALL "IFCMMT" USING RETCODE. ADD 1 TO UPDATE-TOT. * * SUBROUTINE TO WRITE A REPORT RECORD * WRITE-REC. MOVE MAKE TO CAR-MAKE-OUT. MOVE MODEL TO CAR-MODEL-OUT. MOVE YEAR TO CAR-YEAR-OUT. MOVE COLOR TO CAR-COLOR-OUT. WRITE CAR-REC-OUT. * * SUBROUTINE TO DISPLAY HLI CALL ERRORS * ERROR-RTN. IF RETCODE IS EQUAL TO 3 THEN DISPLAY "RECORD LOCKING CONFLICT". CALL "IFERLC" USING RETCODE, RECNUM, USERNUM, FILENAME "RECORD NUMBER = " RECNUM "USER NUMBER = " USERNUM "IN FILE " FILENAME. MOVE RETCODE TO M204-RETCODE-ERROR. DISPLAY "CRITICAL ERROR - UNSUCCESSFUL HLI FUNCTION CALL: " M204-CALL-ERROR ", WITH A RETCODE OF: " M204-RETCODE-ERROR. CALL "IFGERR" USING RETCODE, M204-MSG-ERROR. DISPLAY "MODEL 204 ERROR MESSAGE: " M204-MSG-ERROR. GO TO END-RTN. * * SUBROUTINE TO END THE TRANSACTION * END-RTN. CALL "IFCLOSE" USING RETCODE. CALL "IFFNSH" USING RETCODE. . . . STOP RUN.

Controlling record locking conflicts

Releasing records

Use the following guidelines for releasing records:

  • Release records as soon as you no longer need them. Use IFRELR to release records, including those on a list. (To free pages in CCATEMP, use IFCLST when you no longer need the records in a list.)
  • Place the records you need on a list, release the records, and process from the list in situations where no updates are taking place or where updates are known not to affect the data in question.

Processing update units

Use the following guidelines for processing update units:

  • Use IFCMMT at the end of logical updates and keep logical updates short.
  • If using HLI from an Online monitor, such as CICS, try to keep update units within the same terminal I/O point.

Changes to the database

Use the following guidelines for applications that make changes to the database:

  • In an application that reads and updates, segregate updating functions from read-only functions.
  • Perform the following functions during off-peak hours: IFRFLD, IFNFLD, and IFDFLD.
  • Defer index updates whenever possible. Because exclusive locks are not held as long, deferring index updates speeds updating. Only a part of the work is being done while the lock is held. For more information about index updates, see File Load utility.

See also