Sorting Files | Maintaining 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.
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.
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.
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.
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.
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.
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:
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
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.
select fd-name assign to "muser.dat" ... lock mode is automatic.
Then, a READ statement causes a lock:
read fd-name
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:
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.
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.
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.
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. |
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.
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.
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.
The following sections define the rules that apply for each file organization.
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:
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:
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.
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.
This statement releases record locks on all the records in all the files that the program has opened. This includes SEQUENTIAL, RELATIVE and INDEXED files, with automatic or manual locking on single and multiple records. The COMMIT statement has no effect on exclusive files.
This statement releases record locks on all the records in all the files that the program has opened. This includes SEQUENTIAL, RELATIVE and INDEXED files, with automatic or manual locking on single and multiple records. The ROLLBACK statement has no effect on exclusive files.
The statement
UNLOCK filename
releases all record locks the user has acquired on the specified file.
With sharable files opened for I/O whose LOCK MODE is MANUAL, you must include the WITH LOCK phrase (for single record locks) or WITH KEPT LOCK phrase (for multiple record locks) if a lock is to be obtained on the record.
If you specify the WRITELOCK Compiler directive, the REWRITE and WRITE statements also lock accessed records.
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:
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.
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.
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.
Sorting Files | Maintaining Files |