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.

Note

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.

Note

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.

Tip

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 manual record lock is released when one of the following conditions occur:

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:

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.)