Record locking
Because Synergy programs function in multiuser environments, files opened in update mode are automatically subject to record-level locking controls. No record locking is performed when a file is opened in input mode.
When a record is retrieved from a file opened in update mode, the data record is locked to prevent access to the record by another channel. Synergy DBL provides two types of locking that can be used at the same time on a channel: automatic and manual. Automatic locking releases a lock before locking another record; only one automatic lock exists on a channel. Manual locking locks a record until it is explicitly unlocked; multiple records can be manually locked on the same channel.
On Windows and Unix, manual record locking is available only for ISAM files. If you specify a manual lock on a relative (or other) file, an automatic lock will be applied. OpenVMS allows manual locks on RMS ISAM and relative files. |
The default record locking state is automatic locking. If you specify LOCK:Q_NO_LOCK on the OPEN statement to change the default record locking behavior, no record locking is performed. When locking, a record is locked on an update channel only after a successful READ, FIND (with LOCK), READS, or Select.MoveNext, and no error has been generated except $ERR_KEYNOT and $ERR_RECBIG. $ERR_KEYNOT is only generated without an explicit MATCH qualifier or with MATCH:Q_GEQ.
All locking on Unix is process-based, so be careful when accessing the same file on multiple update channels in the same process. See Record locking on Unix for more information. |
On Windows and Unix, you cannot write to or delete an unlocked record. If you OPEN a file in update mode with the Q_NO_LOCK qualifier, you can use STORE to add new records, but if you attempt to update or delete an existing record using WRITE or DELETE, you’ll get a “No current record” error ($ERR_NOCURR).
On a READ or READS statement on an update channel, you can override the default automatic record locking behavior by specifying the LOCK qualifier. For example, if a file is opened in update mode, you can use the LOCK:Q_NO_LOCK or LOCK:Q_NO_TLOCK qualifier to read a record without locking it, instead of having to perform an UNLOCK after the record is automatically locked.
Manual locking can be used by specifying LOCK:Q_MANUAL_LOCK on either a FIND, READ, READS, or STORE statement or a Select.From constructor lock parameter. Records with manual locks must be explicitly unlocked or released by closing the file. Rereading a manually locked record with a FIND (with lock) , READ, or READS statement that does not specify the Q_MANUAL_LOCK does not remove the manual lock.
A file can have both manual locks and an automatic lock.
If you’re reading a record that could be locked and you don’t plan to immediately update or delete it (for example, you’re displaying the record for examination), we suggest that you either use the LOCK:Q_NO_LOCK qualifier or execute an UNLOCK statement to allow other users to access the record. With xfServer, LOCK:Q_NO_LOCK reduces network overhead compared to a LOCK/UNLOCK combination. |
An automatic record lock is released when one of the following conditions occurs:
- A different record is locked by a FIND, READ, READS, GET, GETS, or Select.MoveNext statement.
- A WRITE statement is used to update a locked record.
- A STORE, FIND, or WRITES statement is used.
- The FREE subroutine is called, which releases all automatic and manual locks.
- The locked record is deleted with the DELETE statement. (The DELETE statement is used with ISAM files only.)
- An UNLOCK statement unlocks the channel.
- The file is closed with the CLOSE statement.
A manual record lock is released when one of the following conditions occur:
- The FREE subroutine is called, which releases all automatic and manual locks.
- The locked record is deleted with the DELETE statement.
- An UNLOCK statement explicitly unlocks the record using the RFA I/O qualifier. On OpenVMS, you can unlock the last record without specifying RFA if the VMS_UNLOCK_SINGLE environment variable is set and system option #35 is not set.
- The file is closed with the CLOSE statement.
When using manual locking on a file with data compression or variable-length records, all record updates (using the WRITE statement) must also update the saved RFA for that record (using GETRFA on the WRITE statement) because the record can be physically moved, thereby changing its file position. Alternatively, you can add the STATIC_RFA file option, which guarantees an RFA that remains static. (We recommend the latter.) STATIC_RFA is the default for all REV6 and higher files.
On Windows and Unix, to retrieve information about locked records, you can run the chklock utility. For more details, see chklock. Depending on which options you specify, chklock returns the following types of information:
- The first byte position of every record that is locked in a file
- The process ID that holds each lock (Unix only)
- The length of each lock (Unix only)
- Whether the file is opened in input or update mode (Unix only)
- Whether the file is locked for exclusive access
Record locking on Windows and OpenVMS
Record locks on Windows and OpenVMS are channel-based. If the same program opens the same file on two different channels in update mode, both channels will be affected by each other’s locks, which may cause unexpected $ERR_LOCKED errors.
Record locking on Unix
Locks on Unix are process-based; if the same program opens the same file on two different channels in update mode, one channel won’t be affected by the other’s locks. Also, if the same record is read by both channels, the record will be unlocked by one channel without the other channel being aware of it. This means the record can be overwritten even when another user now has a lock. For this reason, we recommend that when opening the same file on another channel, it be in input mode rather than both in update mode.
If a user opens a file on more than one channel, Synergy DBL defers the actual system closing of the file until it has been closed on all channels opened by that user. This feature is necessary to maintain locks set by the other open channels, because on Unix the system close releases all locks in the file held by the process, even if some of those locks were applied to a different channel that remains open. When the file is closed on one of the channels but remains open on other channels, Synergy DBL “holds” the channel until the file has been closed on all of the channels. All known record locks on the channel being closed are still unlocked, and all locks held on other channels remain locked, so no adverse effects due to this behavior should occur.
Optimistic locking technique
Synergy DBL also makes it possible for you to take advantage of optimistic record locking. Optimistic locking is a technique that cuts down on lock contention by shortening the duration of record locks during update operations. An application using an optimistic locking model during transactions will have two types of I/O operations: a get operation and an update operation. The get operation either reads a record without a lock (LOCK:Q_NO_LOCK) or reads it with a lock and then immediately unlocks it. The update operation occurs at the end of the transaction, by rereading the same record with a lock and then immediately writing out the new record and unlocking it.
Determining whether or not the record was changed is a key requirement of optimistic locking. Using GRFAs is one way to fill that requirement. When you initially read the record, you should save the GRFA that is returned, so that subsequently when you reread the record in your update phase, it can be used to ensure the record has not changed. This is automatically done by the READ statement using the RFA qualifier with the saved GRFA. If another processes has modified the record, a “Record not same” error ($ERR_RECNOT) is generated, but the record is still retrieved (but not locked). By trapping the error, you can adjust your processing using both versions of the record to appropriately handle the condition. (See Record file addresses (RFAs), GETRFA, and RFA for more information about GRFAs.)