# Compaq COBOL
User Manual

Previous | Contents | Index

# 8.4 Ensuring Successful Record Locking

Once you meet all of the file-sharing criteria and you access a file, you can consider two record-locking modes that control access to records in a file:

- Automatic record locking---The system automatically releases an existing record lock whenever a new record is accessed and acquires a record lock whenever it reads a record in the file.
- Manual record locking---A file connector can hold a number of record locks simultaneously. Manual record locking is available only for relative or indexed files.

Note You must use the same method for record locking as for file sharing. For any single file connector, you cannot mix the X/Open standard (Alpha) and the Compaq standard methods.

## 8.4.1 X/Open Standard Record Locking (Alpha)

This section describes the X/Open standard method of specifying automatic or manual record locking.

Specifying Automatic Record Locking (X/Open Standard) (Alpha)

You specify X/Open standard automatic record locking in the Environment Division by using LOCK MODE IS AUTOMATIC [WITH LOCK ON RECORD] on the SELECT statement. (The optional WITH LOCK ON RECORD clause has no effect and is for documentation only.) Subsequently, a record lock is acquired by the successful execution of a READ statement. (The WITH LOCK clause is not necessary on the READ; it is implied.)

A record lock is released by one of the following events:

- The successful execution of a subsequent I-O statement
- Using the UNLOCK statement
- Closing the file, implicitly or explicitly

In X/Open standard record locking, only the READ statement can acquire a lock. You can use the WITH NO LOCK phrase of the READ statement to prevent the acquiring of an automatic record lock.

For files opened in INPUT mode, READ and READ WITH LOCK statements do not acquire a record lock.

Specifying Manual Record Locking (X/Open Standard) (Alpha)

You specify X/Open standard manual record locking in the Environment Division by using LOCK MODE IS MANUAL WITH LOCK ON MULTIPLE RECORDS on the SELECT statement. Manual record locking is available only for relative and indexed files.

For manual record locking, a record lock is acquired by specifying the WITH LOCK phrase on the READ statement. READ is the only operation that can acquire a lock. The record lock is released by one of the following events:

- Using the UNLOCK statement (any form of the UNLOCK statement unlocks all record locks held by the current access stream; there is no singular option)
- Closing the file, implicitly or explicitly

The WITH LOCK clause is ignored for files opened in INPUT mode. Locks are detected but not acquired.

Example 8-4 is a partial example of using both methods of X/Open standard record locking.

Example 8-4 X/Open Standard Record Locking (Alpha)

    User 1 (Automatic Record Locking): ---------------------------------

    FILE-CONTROL.
             SELECT FILE-1
                  ORGANIZATION IS RELATIVE
                  ASSIGN TO "SHAREDAT.DAT"
                  LOCK MODE AUTOMATIC.
                  .
                  .
                  .
    PROCEDURE DIVISION.
    BEGIN.
    OPEN I-O FILE-1.
    READ FILE-1.
                  .
                  .
                  .
    REWRITE FILE-1-REC.
    CLOSE FILE-1.
    STOP RUN.

    User 2 (Manual Record Locking): ------------------------------

    FILE-CONTROL
             SELECT FILE-1
                  ORGANIZATION IS RELATIVE
                  ASSIGN "SHAREDAT.DAT"
                  LOCK MODE MANUAL LOCK ON MULTIPLE RECORDS.
                  .
                  .
                  .

    PROCEDURE DIVISION.
    BEGIN.
    OPEN I-O FILE-1.
                  .
                  .
                  .
    READ FILE-1 WITH LOCK.
    REWRITE FILE-1-REC.
    UNLOCK FILE-1.
    CLOSE FILE-1.
    STOP RUN.

Note that User 2 could have employed AUTOMATIC record locking just as well. In this case, manual and automatic locking work similarly. <>

## 8.4.2 Compaq Standard Record Locking

Automatic Record Locking (Compaq Standard)

You specify automatic record locking by using the ALLOWING phrase of the OPEN statement. The lock is applied when you access the record and released when you deaccess the record. In automatic record locking the access stream can have only one record locked at a time and can apply only one type of lock to the records of the file.

You deaccess a record by using the next READ operation, a REWRITE or a DELETE operation on the record, or by closing the file. In addition, you can release locks applied by automatic record locking by using the UNLOCK statement.

In automatic record-locking mode, you can release the current record lock by using an UNLOCK RECORD statement or an UNLOCK ALL RECORDS statement. (On Tru64 UNIX systems for indexed files only, there is no current record lock.) However, because in automatic record locking you can lock only one record at a time, the UNLOCK ALL RECORDS statement unnecessarily checks all records for additional locks.

The sample program in Example 8-5 uses automatic record locking. The program opens the file with I-O ALLOWING ALL. Another access stream in another program also opens the file with INPUT ALLOWING ALL.

Note that two parallel access streams use the program in Example 8-5.

If the first access stream is updating records in random order, a record lock can occur to the second stream from the READ until the REWRITE statement of the first stream. Record locks can also occur to the first stream when the second stream reads a record and the first stream tries to read the same record.

Example 8-5 Automatic Record Locking (Compaq Standard)

    SELECT FILE-1
         ORGANIZATION IS RELATIVE
         ASSIGN TO "SHAREDAT.DAT"
         .
         .
         .
    PROCEDURE DIVISION.
         OPEN I-O FILE-1 ALLOWING ALL.
         READ FILE-1  AT END DISPLAY "end".
              .
              .
              .
         REWRITE FILE-1-REC.
         CLOSE FILE-1.
         STOP RUN.

When you close a file, any existing record lock is released automatically. The UNLOCK RECORD statement releases the lock only on the current record on OpenVMS systems, which is the last record you successfully accessed. On Tru64 UNIX systems for indexed files only, there is no current record lock.

Manual Record Locking (Compaq Standard)

You specify manual record locking by using the APPLY LOCK-HOLDING clause (in the I-O-CONTROL paragraph), the OPEN ALLOWING statement, and the ALLOWING clauses on the Compaq COBOL record operations (except DELETE). Manual record locking allows greater control of locking options by permitting users to lock multiple records in a file and by permitting different types of locking to apply to different records.

Manual record locking applies the specified lock when you access the record and releases the lock when you unlock the record.

When you specify manual record locking, you must use all of the following clauses:

- An APPLY LOCK-HOLDING clause in the I-O CONTROL paragraph
- An OPEN ALLOWING clause at file open time
- An ALLOWING clause on each record operation (except DELETE)2

The possible ALLOWING clauses for the record operations (that is, the READ, WRITE, REWRITE, and START statements) are as follows:

- ALLOWING NO OTHERS2---Locks records for exclusive access. Others cannot perform READ, WRITE, DELETE, or UPDATE statements. This clause constitutes a lock for write and does not allow readers.
- ALLOWING READERS---Locks records against WRITE, REWRITE, and DELETE access by all streams including the stream that issues the statement. Others can perform READ statements.
- ALLOWING UPDATERS2---Does not apply any locks to the records. Others can perform READ, REWRITE, and DELETE statements. This clause constitutes a no record lock condition. 2

However, if the file's OPEN mode is INPUT, using the ALLOWING clause on the record operation does not lock the record.

On Tru64 UNIX systems, for indexed files only, the WRITE, REWRITE, and START statements do not acquire a record lock.

On Tru64 UNIX systems for indexed files only, ALLOWING READERS is treated as ALLOWING NO OTHERS if the file is opened in I-O mode or as ALLOWING ALL if the file is opened in INPUT mode. <>

Table 8-5 shows the valid and invalid ALLOWING combinations for manual record locking. The columns represent the lock held, and the rows represent the lock requested.

Table 8-5 Manual Record Locking Combinations
|  | Lock Held (for first stream)
--- | --- | ---
I-O Attempt (for subsequent stream) | Updaters | Readers | No Others
READ | Allowing Updaters | Y | Y | N
| Allowing Readers | Y | Y | N
| Allowing no others | Y | N | N
REWRITE | Allowing no others | Y | N | N
DELETE |  | Y | N | N
START | Allowing Updaters | Y | Y | N
| Allowing Readers | Y | Y | N
| Allowing no others | Y | Y | N
WRITE | Allowing no others | N/A | N/A | N/A

    Legend: Y = Subsequent stream executes successful I-O operation
            N = Subsequent stream I-O operation is unsuccessful (File Status 92)

Example 8-6 uses manual record locking. The file is opened with the ALLOWING ALL clause. The records are read but do not become available to other access streams because of the lock applied by the READ statement (READ...ALLOWING NO OTHERS). When the UNLOCK is executed, the records can be read by another access stream if that stream opens the file allowing writers.

Example 8-6 Sample Program Using Manual Record Locking (Compaq Standard)

    FILE-CONTROL.
        SELECT FILE-1
             ORGANIZATION IS RELATIVE
             ASSIGN "SHAREDAT.DAT".
              .
              .
              .
        I-O-CONTROL.
             APPLY LOCK-HOLDING ON FILE-1.
              .
              .
              .
    PROCEDURE DIVISION.
    BEGIN.
         OPEN I-O FILE-1 ALLOWING ALL.
              .
              .
              .
         READ FILE-1 ALLOWING NO OTHERS AT END DISPLAY "end".
              .
              .
              .
         REWRITE FILE-1-REC ALLOWING NO OTHERS.
              .
              .
              .
         UNLOCK FILE-1 ALL RECORDS.
         CLOSE FILE-1.
         STOP RUN.

In manual record locking, you release record locks by the UNLOCK statement or when you close the file (either explicitly or implicitly; when you close a file, any existing record lock is released automatically). The UNLOCK statement provides for either releasing the lock on the current record (on OpenVMS systems with UNLOCK RECORD) or releasing all locks currently held by the access stream on the file (UNLOCK ALL RECORDS). (On Tru64 UNIX systems for indexed files only, there is no current record lock.)

When you access a shared file with ACCESS MODE IS SEQUENTIAL and use manual record locking, the UNLOCK statement can cause you to violate either of the following statements: (1) the REWRITE statement rule that states that the last input-output statement executed before the REWRITE must be a READ or START statement, or (2) the DELETE statement rule that states that the last input/output statement executed before the DELETE statement must be a READ. You must lock the record before it can be rewritten or deleted.

Releasing Locks on Deleted Records

In automatic record locking, the DELETE operation releases the lock on the record. In manual record-locking mode, you can delete a record using the DELETE statement but still retain a record lock. You must use the UNLOCK ALL RECORDS statement to release the lock on a deleted record.

If a second stream attempts to access a deleted record that retains a lock, the second stream will receive either a "record not found" exception or a hard lock condition. (See Section 8.4.3 for information on hard lock conditions.)

On OpenVMS, if another stream attempts to REWRITE a deleted record for which there is a retained lock, the type of exception that access stream receives depends on its file organization. If the file organization is RELATIVE, the access stream receives the "record locked" status. If the file organization is INDEXED, the access stream succeeds (receives the success status).

In relative files, the lock is on the relative cell (record) and cannot be rewritten until the lock is released. On indexed files, the lock is on the record's file address (RFA) of the deleted record, so a new record (with a new RFA) can be written to the file. <>

Bypassing a Record Lock

When you use manual record locking, you can apply a READ REGARDLESS or START REGARDLESS statement to bypass any record lock that exists. READ REGARDLESS reads the record and applies no locks to the record. START REGARDLESS positions to the record and applies no locks to the record. If the record is currently locked by another access stream, a soft record lock condition can be detected by a USE procedure. (See Section 8.4.3 for information on soft record locks.)

You use READ REGARDLESS or START REGARDLESS when: (1) a record is locked against readers because the record is about to be written, but (2) your access program needs the existing record regardless of the possible change in its data.

Note You should recognize that READ REGARDLESS and START REGARDLESS are of limited usefulness. They can only reliably tell the user whether a record exists with a given key value. They cannot guarantee the current contents of the data in the record. You prevent the use of READ REGARDLESS or START REGARDLESS at the file protection level when you prevent readers from referencing the file. You can use READ REGARDLESS and START REGARDLESS during sequential file access to force the File Position Indicator.

When you close a file, any existing record lock is released automatically. The UNLOCK RECORD statement releases the lock only on the current record on OpenVMS systems, which is the last record you successfully accessed. On Tru64 UNIX systems for indexed files only, there is no current record lock.

## 8.4.3 Error Handling for Record Locking

This section describes the locking error conditions and the two kinds of locks: hard and soft.

Note Soft record locks are available for Compaq standard record locking but are not part of X/Open standard (Alpha). Soft record lock conditions also do not occur on the Tru64 UNIX system for indexed files.

Any record contention error results in an unsuccessful statement for which a USE procedure will be invoked. A "record-locked" condition results in an I-O status code of 92.

Interpreting Locking Error Conditions

Two record-locking conditions (hard and soft record lock) indicate whether a record was transferred to the record buffer. Compaq COBOL provides the success, failure, or informational status of an I/O operation in the file status variable.

Hard Record Locks

A hard record lock condition, which causes the file status variable to be set to 92, indicates that the record operation failed and the record was not transferred to the buffer. A hard record lock results from a scenario such as the one shown in the following steps, which uses Compaq standard manual record-locking mode:

1. Program A opens the file I-O ALLOWING ALL.
2. Program A reads a record ALLOWING NO OTHERS.
3. Program B opens the file I-O ALLOWING ALL.
4. Program B tries to access the same record as A.
5. Program B receives a hard record lock condition.
6. The record is not accessible to Program B.
7. Program B's File Status variable is set to 92.
8. Program B's USE procedure is invoked.
9. Program A continues.

The record was not available to Program B.

On Tru64 UNIX, for INDEXED files, READ with the ALLOWING UPDATERS clause as well as any START statement will not detect a locked record. Potential conflicts do not trigger a hard lock condition, only actual conflicts do. <>

Soft Record Locks

Soft record locks can occur only with Compaq standard record locking. A soft record lock condition, which causes the file status variable to be set to 90, indicates that the record operation was successful, the record was transferred to the buffer, and a prior access stream holds a lock on that record. A soft record lock can be detected by a USE procedure. This condition occurs in either of the following two situations:

- When a record is accessed in a file that has been opened in INPUT mode, a soft record lock condition may occur if the record has been locked by a prior stream. This depends on the type of lock held by the first stream and requested by the subsequent stream.
- In the second situation, a stream attempts to access a record that has been locked by another stream. The second stream employs a READ REGARDLESS or START REGARDLESS statement (see Bypassing a Record Lock), which overrides the hard record lock and allows access to the record. The second stream sucessfully reads the record and receives a soft record lock. (The second stream cannot update the record.)

For example, a soft record lock results from a situation such as the following, which uses automatic record-locking mode:

1. Program A opens the file I-O ALLOWING READERS.
2. Program A reads a record.
3. Program B opens the file INPUT ALLOWING ALL.
4. Program B reads the same record.
5. Program B receives a soft record lock condition. The record is accessible to Program B.
6. Program B's File Status variable is set to 90.
7. On OpenVMS, Program B's USE procedure (if any) is invoked. <>
8. Programs A and B continue.

The record was available to Program B.

Note A file (and thus the records in it) cannot be shared if automatic or manual record locking is not specified by the user.

A manual record-locking environment is required in order for the REGARDLESS and ALLOWING options to be used on a READ statement. The READ REGARDLESS and START REGARDLESS statements should be used only when the access program clearly needs the existing record regardless of the possible imminent change in its data. For a full description of the OPEN, READ, and START statements and their options, refer to the Compaq COBOL Reference Manual.

Soft Record Locks and Declarative USE Procedures

If a soft record lock occurs, the values of the following variables for the current file are undefined until the execution of any applicable Declarative USE procedure is complete:

- Record buffer
- RELATIVE KEY
- DEPENDING ON

These variables remain undefined if the Declarative USE procedure terminates with an EXIT PROGRAM statement.

Hard Record Locks and File Position During Sequential Access

If a hard record lock condition occurs for a sequential READ statement, the file position indicator is unaffected. If the application must continue reading records, the following actions may be taken:

- Compaq standard record locking
  START or READ REGARDLESS may be used to bypass a hard record lock (see Soft Record Locks).
- X/Open standard record locking
  For indexed and relative files, a START statement, with the appropriate KEY clause, may be used to skip the record that is locked. On Alpha, because X/Open START statements do not detect or acquire a record lock, some file processing may still be possible. However, users must be aware that this is not typical sequential file processing, as not all records will be retrieved.

Error Handling Example

Example 8-7 is an example of processing locked record conditions.

Example 8-7 Program Segment for Record-Locking Exceptions

    FILE-CONTROL.
        SELECT file-name ASSIGN TO "fshare.dat"
               FILE STATUS IS file-stat.

    WORKING-STORAGE SECTION.
    01  file-stat PIC XX.
        88 record-ok     VALUES "00", "02", "04".
        88 record-locked VALUE  "92".
    01  RETRY-COUNT  PIC 9(2).
    01  MAX-RETRY    pic 9(2) VALUE 10.
        .
        .
        .
    PROCEDURE DIVISION.
    DECLARATIVES.
    FILE-USE SECTION.  USE AFTER STANDARD EXCEPTION PROCEDURE ON file-name.
    FILE-ERR.
    * need declaratives to trap condition, but let main code process it.
    * invalid key clause does not apply

            IF record-locked
               continue
            ELSE
               .
               .
               .
            END-IF.
    END DECLARATIVES.
    MAIN-BODY SECTION.
    BEGIN.
        DISPLAY "From main-body".

        .
        .
        .
    GET-RECORD.
          READ file-name.
          IF NOT record-ok
             PERFORM check-read.
          .
          .
          .
    CHECK-READ.
          IF record-locked
             MOVE 1 to retry-count
             PERFORM retry-read UNTIL record-ok OR
                                      retry-count > max-retry
             IF record-locked AND retry-count > max-retry
                DISPLAY "Record is unavailable...enter new record to retrieve: "
                         WITH NO ADVANCING
                ACCEPT record-id
                GO TO get-record
             END-IF
          END-IF.

    * handle other possible errors here

    RETRY-READ.
         READ file-name.
         add 1 to retry-count.

Note #### 2 Some exceptions exist on Tru64 UNIX. Refer to the Compaq COBOL Reference Manual for details.

Previous | Next | Contents | Index