PreviousSorting Files Maintaining FilesNext"

Chapter 6: Sharing Files

This COBOL system enables COBOL programs to share data files in a multi-user environment, giving each program access to common data files, while maintaining data integrity.

This chapter describes the facilities which enable you to create multi-user file handling applications and demonstrates how to use them. It also describes the sample programs provided.

6.1 Overview

You specify file sharing using COBOL syntax in your program. See your Language Reference for full details of this syntax.

If you are running your COBOL application in a single-user environment, this multi-user syntax has no effect. This enables you to develop applications designed for use in multi-user environments in a single-user environment.

6.2 File and Record Locking

When you have a file containing data that you want to be shared between several users on a network (or any multi-user, multi-tasking operating system), you want to prevent more than one user from changing the same data at the same time. This involves locking the data.

There are several ways to lock data in COBOL. You can lock either a single record or multiple records - this is called record locking. Or, you can lock a whole file - this is called file locking or exclusive locking.

If the user locks the whole file (called an exclusive lock), no other user can access that file. If the user locks records (either single record locks or multiple record locks), the file is shareable with other users. Other users may also lock records in the same file. Each user can lock a single record or multiple records. Any user can access any data that is not locked by another user.

Your program can open several data files at the same time, and can specify locking for each data file that is opened. However, you can have only one type of locking for each file - that is, locking of the whole file, locking of a single record or locking of multiple records.

Figure 6-1 illustrates a typical multi-user environment.



Figure 6-1: A Typical Multi-user Environment

If you use record locking, you can specify whether you want a lock whenever a record is read - this is called automatic record locking, or only when you explicitly specify a lock - this is called manual record locking.

You set up the type of lock you want in the SELECT clause for the file.

Whenever you are using record or file locking, you should add file status checking to your program to interrogate the status codes pertaining to locking.

6.2.1 Default locking

When you do not explicitly specify locking in your program, files opened I/O, OUTPUT or EXTEND acquire an exclusive lock by default. That is, the whole file is locked by your program. If, however, your program opens the file for INPUT, the file becomes shareable (read-only), and your program cannot hold record locks on it; other users can open the file for INPUT but they cannot acquire record or file locks on it.

6.2.2 Locking Files

With file locking, whenever one user has a file open, other users cannot access the same file. Any file organization can be locked in this way.

Your program cannot open a file in exclusive mode if another user is already accessing the file. With exclusive locking, the file remains locked until it is closed. If your program opens a file for OUTPUT or a relative or indexed file for EXTEND, this implies an exclusive lock on the file.

To obtain an exclusive lock on a file, you must have operating system read and write permission for that file.

When a user tries to access a file that is locked exclusively, the file status returned is 9/065.

With line sequential files, file locking is the only type of locking that is permitted.

Example

     select fd-name
         assign to "muser.dat"
            ...
         lock mode is exclusive.

The LOCK MODE phrase sets up the file lock when the file is opened. This prevents any other user from accessing the file at the same time.

6.2.3 Locking Records

With record locking, several users can access the same file, except for those records that are actually locked by another user.

When you try to access a record that is locked by another user, the file status returned is 9/068.

If you want to use record locking, you must OPEN the file I-O. Only files on shared drives can have record locks applied to them.

With automatic record locking, record locks are automatically acquired on every READ statement except when WITH NO LOCK is specified. With manual record locking, the READ statement must explicitly use the WITH LOCK or WITH KEPT LOCK clause to lock the record being read.

Automatic record locking is easier to use, but if you do not want your program to lock every record that it reads (because of contention problems, for example), you need to use manual record locking.

6.2.3.1 Single Record Locking

A program that specifies single record locking for a file (either explicitly or implicitly) can hold only one record lock in that file at any one time. Such a program can acquire a single record lock in one of two ways: manually or automatically.

The lock is released when the program does one of the following:

6.2.3.1.1 Manual Single Record Locking

You can specify manual single record locking by using the LOCK MODE IS MANUAL clause in the SELECT statement for a file. Your program can then acquire a record lock on any individual record within that file by accessing the record using a READ WITH LOCK statement.

Example

select fd-name
         assign to  "muser.dat"
             ...
         lock mode is manual.

With manual locking, the READ statement must explicitly ask for the lock:

     read fd-name with lock
6.2.3.1.2 Automatic Single Record Locking

You can specify automatic single record locking by using the LOCK MODE IS AUTOMATIC clause in the SELECT statement for a file. Your program then automatically acquires a single record lock when it reads a record in that file.

Example
     select fd-name
         assign to "muser.dat"
            ...
         lock mode is automatic.

Then, a READ statement causes a lock:

     read fd-name

6.2.3.2 Multiple Record Locking

A program that specifies multiple record locking for a file can simultaneously hold several record locks. Multiple record locks for a program can be acquired in either of two ways: manually or automatically.

With either method, if you use the WRITELOCK Compiler directive, a multiple record lock is acquired whenever your program accesses the file with a WRITE or REWRITE statement.

These locks are released when your program does one of the following:

6.2.3.2.1 Manual Multiple Record Locking

You specify manual multiple record locking by using the LOCK MODE IS MANUAL WITH LOCK ON MULTIPLE RECORDS clause in the SELECT statement for a file. Your program can then acquire a lock by accessing a record with a READ WITH KEPT LOCK statement.

Example

     select fd-name
         assign to "muser.dat"
            ...
         lock mode is manual
             with lock on multiple records.

Then, if a READ statement asks for a KEPT lock, a lock is obtained for the record:

     read fd-name with kept lock

A DELETE statement releases the lock on an individual record.

6.2.3.2.2 Automatic Multiple Record Locking

You specify automatic multiple record locking by using the LOCK MODE IS AUTOMATIC WITH LOCK ON MULTIPLE RECORDS clause in the SELECT statement for a file. Your program then acquires an automatic multiple record lock whenever it reads a record in the file.

Example

     select fd-name
         assign to "muser.dat" 
             ...
         lock mode is automatic
             with lock on multiple records.

A simple READ statement acquires a lock:

     read fd-name

A DELETE statement releases the lock on an individual record.

6.3 File Status Codes

If you are using file or record locking, you should check for the following file status codes.

9/065 File is locked - another program has locked the file to the exclusion of other programs. Returned after an OPEN operation.
9/068 Record is locked - another program has already locked the record. Returned after a READ, DELETE or REWRITE operation.
9/213 Too many locks - the maximum number of locks has been reached. This number depends on the configuration of your network or operating system.

6.4 Encountering a Locked Record

When a read operation encounters a locked record, the record pointer is not changed, and a file status of 9/068 (record locked) is returned. However, the record data is returned to your program. You can change this behavior using one or more of the following:

The NODETECTLOCK Compiler directive and the B run-time switch have no effect if your program explicitly or implicitly performs a READ WITH LOCK. (An implicit READ WITH LOCK occurs if LOCK MODE IS AUTOMATIC is used in the SELECT statement for the file or if your program is compiled with the AUTOLOCK Compiler directive.)

The following table shows what happens when a second user attempts to perform a READ NEXT on a record which is already locked.

Compiler Directive Switch Retries Status CRP
- - No 9/68 NOT ADV
NODETECTLOCK - No 0/0 ADV
- +B No 9/68 ADV
NODETECTLOCK +B No 0/00 ADV
RETRYLOCK - Yes 0/00 ADV
RETRYLOCK +B Yes 0/00 ADV
RETRYLOCK NODETECTLOCK - No 0/00 ADV
RETRYLOCK NODETECTLOCK +B No 0/00 ADV

CRP = Current Record Pointer
ADV = Advanced
NOT ADV = Not advanced

When a program encounters a locked record, the record data is retrieved. If you want your program to be able to process the data even though the record is locked, you can do so, but you cannot REWRITE the record until it is unlocked, and you have read it again to set up your lock on the record. By this time, the contents of the record may have changed.

A START operation does not indicate whether the target record is locked. Only by reading the record can you discover whether it is locked.

6.5 OPEN WITH LOCK

There is a Micro Focus extension to the OPEN statement which causes an exclusive lock to be held on the file, no matter what was specified in the SELECT clause. This extension is OPEN WITH LOCK:

open fd-name with lock

This statement replaces any record locking established in the SELECT statement with an exclusive lock on the file.

6.6 Examples of File and Record Locking

The following examples illustrate the use of file status with OPEN I-O statements.

Example 1

This example uses no multi-user syntax so the file is locked exclusively.

     select fd-name
         assign "myfile.dat"
         file status is file-status
             ...
 fd fd-name.
 01 x-file-record            pic x(80).
         ...
 01 file-status.
         ...
     open i-o fd-name.
        ...
     if status-byte-2 = 065
        ...

The program checks for file status code 9/065, which indicates a locked file.

Example 2

In this example, automatic record locking is specified so that as the program reads a record, the record is locked out from other users.

     select fd-name
         assign "myfile.dat"
         lock mode is automatic
         file status is file-status.
             ...
 01 file-status.
             ...
     open i-o fd-name
             ...
     read fd-name
      at end
            ...
     if status-byte-2 = 068
         ...

As another user may have already locked the record, the program checks for file status code 9/068.

Example 3

In this example, manual locking is specified. To lock a record, the READ statement must specify WITH LOCK. As WITH LOCK ON MULTIPLE RECORDS is not specified, single record locking is used.

OPEN I-O, single record, lock mode manual:

     select fd-name
        assign "myfile.dat"
         lock mode is manual
         file status is file-status.
            ...
 01 file-status.
            ...
     open i-o fd-name
            ...
     read fd-name with lock
      at end
            ...
     if status-byte-2 = 068
            ...

As another user may have already locked the record, the program checks for file status code 9/068.

Example 4

In this example, automatic locking is specified, so every READ statement acquires a lock. As WITH LOCK ON MULTIPLE RECORDS was specified, locks continue to accumulate until a CLOSE, COMMIT or UNLOCK statement is executed.

     select fd-name
         assign "myfile.dat"
         lock mode is automatic
             with lock on multiple records
         file status is file-status.
             ...
 01 file-status.
         ...
     open i-o fd-name
         ...
     read fd-name at end
          ...
     if status-byte-2 = 068
         ...

As another user may have locked the record, the program checks for file status code 9/068. If there is a chance of the maximum number of record locks being reached, you may want to check for a status code of 9/213.

6.7 Locking Rules for Each File Organization

The following sections define the rules that apply for each file organization.

6.7.1 Record Sequential, Relative and Indexed Files

With record sequential, relative and indexed files you can lock whole files, individual records or groups of records, up to the maximum allowed by your system.

You can hold locks on several records simultaneously using the WITH LOCK ON MULTIPLE RECORDS clause in the SELECT statement. Once you have locked the maximum number of records allowed by your implementation, a status of 9/213, "too many locks", is returned if you try to lock any more records. When this happens you must close the file, or execute a COMMIT , ROLLBACK or UNLOCK statement to release these record locks.

You can lock single or multiple records in either MANUAL or AUTOMATIC locking mode.

Each time your program accesses a file with an OPEN, READ or READ WITH LOCK statement, the locking you have specified in the SELECT statement is taken into account (see the Language Reference for details of these statements). The following then applies:

6.7.2 Line Sequential Files

With line sequential files, you can only lock the file; record locking is not allowed. See your Language Reference for the format of the SELECT statement for a line sequential file.

Each time your program accesses a file with an OPEN, READ or READ WITH LOCK statement, the locking you have specified is taken into account (see the Language Reference for details of these statements). This means that:

6.7.3 All File Types

32-bit:
On 32-bit systems, you can set a cobconfig tuneable to force multiple opens of the same file in a single run-unit to behave in the same way as opens in separate run-units.

This feature is enabled by setting the same_proc_excl_detection cobconfig run-time configurable to TRUE.

UNIX:
Implementation of DOS and OS/2 file handling compatibility code within this COBOL system means that on UNIX, because of the way in which UNIX handles file locks, if a file is opened twice by the same program, and that file is subsequently closed using a file descriptor (FD) received from one of the open operations, any locks obtained by the other open operation are lost. This is the expected behavior of a close operation, as described in the POSIX standard X/Open guidelines.

The run-time tunable posix_lock_prob provides compatibility with the behavior exhibited in V3.0. To emulate this behavior, set posix_lock_prob to TRUE:

set posix_lock_prob=TRUE

See your "Object COBOL User Guide" for full details on the posix_lock_prob run-time tunable.

6.8 Programming Considerations

In most instances, COBOL programs designed to be run in a multi-user environment do not require any extra considerations in the Procedure Division. The exception to this is checking the file status for a lock condition (see the section File Status Codes above). There are, however, some instances where you need to use different syntax in the Procedure Division. This syntax is described below.

If you specify the WRITELOCK Compiler directive, the REWRITE and WRITE statements also lock accessed records.

6.9 Sample Programs

Your COBOL system includes a suite of programs that demonstrate the use of file and record locking in a multi-user environment. The sample programs are:

Program
Description
mudemo.cbl The controlling program. This program displays information about the suite, and presents the user with a choice of access and input modes. Depending on the user's choice, one of the following four subprograms is called.
stockin.cbl Demonstrates opening a shared data file, for input only.
stockioa.cbl Demonstrates opening a shared data file for I/O, with automatic record locking.
stockiom.cbl Demonstrates opening a shared data file for I/O, with manual record locking.
stockout.cbl Demonstrates opening a shared data file for output only.

6.9.1 Running the Sample Programs

Compile the programs listed above in the usual way and move the resulting executable files to an area where they can be accessed simultaneously from two terminals. You must make sure that the two terminals are accessing the same file. Invoke the multi-user demonstration programs on both terminals. Both screens display the initial screen as shown in Figure 6-2.



Figure 6-2: Initial Screen of mudemo

When the initial screen is displayed, choose the access and lock mode by pressing the number associated with the required mode, followed by Enter. Once you have chosen, the relevant subprogram is called by the main program Mudemo, and another screen is displayed. This screen shows a stock control system with stock code, stock description, stock held and cost per unit. The bottom of the screen shows the open and lock modes, what the last operation was, whether it was successful, and the file status. Again, a choice of operations is presented.

6.9.1.1 Creating the file

The first thing you must do to set up the multi-user environment is to create a data file that two users can share. You can create the file by selecting input choice 4 to open the file for OUTPUT.



Figure 6-3: Screen to Create a New Record

When the screen shown in Figure 6-3 is displayed, enter data in the stock code, stock description, stock held and cost per unit fields using the Tab key to move from field to field.

When these fields are complete, the data can be written to the data file mustock by selecting option 1 (write record) and pressing Enter. Write five or six records in this way and then close the file by selecting option 2.

While the first user is doing this, the second user can try to access the data file mustock, but will fail because opening a file for output locks the file exclusively. The second user will receive a "file locked" status.

6.9.1.2 Sharing the file

If the first user selects 2, for I/O Lock Mode Automatic at the initial screen, the screen shown in Figure 6-4 is displayed. To access the first record, move down to the Input Choice field by pressing End twice. Now press 2 to read the next record. The first record in mustock is displayed.



Figure 6-4: Preparing to Read the Next Record

The first record in the data file mustock is now locked by the first user, and remains so until this user next accesses the file. The second user can access any other record in the file by selecting to open the file for I/O Lock Mode Automatic or for Input, for example. The second user can execute a "start not less than", thus avoiding the first record in the file that is locked by the first user.

The second user can access the first record, but receives a file status of "Record locked". However, the data is returned unless the operating system does not support this.

Try the various combinations of locking and access for yourself so that you become familiar with the way this COBOL system locks data.


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousSorting Files Maintaining FilesNext"