Product Documentation

FairCom ISAM for C

Previous Topic

Next Topic

Low-Level Data Record Locks

Record locking controls which user is able to access and update a given record. There are four basic locking modes: ctENABLE, ctENABLE_BLK, ctFREE, and ctREADREC. These modes have the same meaning as with the LockISAM() function.

The LockCtData() function is used when using low-level functions to access the database. LockCtData() differs from LockISAM() in that it affects only a single record, as specified when the LockCtData() function is called.

ctENABLE

Places a write lock on a given record. Only one user can have a write lock on a given record. It also prevents another user from getting a read lock. This is used when a user wants to update a record, and wants to prevent any other user from updating at the same time. You can think of this as an exclusive record lock.

ctENABLE_BLK

This is the same as ctENABLE, but the process will “go to sleep” until the lock is granted. With ctENABLE, if a lock cannot be granted, LockCtData() returns error code DLOK_ERR (42). With ctENABLE_BLK, FairCom DB waits until the other user releases the lock so that you can obtain it. This should be used with caution. If FairCom DB detects a dead lock situation, error DEAD_ERR will be returned. For example, if User A has a lock on record 1 and is waiting for a lock on record 2, while User B has a lock on record 2 and is waiting for a lock on record 1, they are deadlocked.

ctFREE

Use this lock mode to release a lock on a specific record.

ctREADREC

This is a read lock. Any number of users can have a read lock on a record simultaneously. This ensures that no other user can acquire a write lock on the record. Think of this as a shared record lock. However, a single write lock prevents any read locks from being acquired.

ctREADREC_BLK

This is the same as ctREADREC except that with the FairCom Server, a process not able to get a read lock will “go to sleep” until the lock is available.

Previous Topic

Next Topic

FairCom Server enhanced locking control for files opened multiple times in the same connection

Starting in V10.3, FairCom DB supports opening the same file multiple times in the same connection assigning a different file number to each file or, in c-treeDB, a different file handle. This can be useful in situations where you want to allow the same file to be opened twice by the same thread with different locking attributes applied to each thread.

Each of these sibling files is referred to as a "co-file." For example, if the file customer.dat is opened in the same connection using file numbers 5 and 10, then we say that file 5 is a co-file of file 10, and vice versa.

In this case there are considerations about how locks interact within the same connection when operating using different co-files. For example, if a write lock is acquired on a record R using file number 5 within the same connection, what is the behavior of trying to acquire a lock on R using co-file number 10?

In this example, before this enhancement, FairCom Server behaved as follows:

The lock on R issued with co-file number 10 succeed and is considered a "secondary lock", while the lock acquired first (using file number 5) is considered "primary."

The difference in the locks manifests itself during calls to unlock the record: If the primary lock is unlocked first, then the primary lock and all the corresponding locks on co-files are removed. But if a secondary lock is unlocked before the primary lock is unlocked, then only the secondary user lock is removed; and the primary lock is maintained.

Any other connection saw the record locked until the primary lock was released.

This previous behavior has been maintained and it is the system-level default behavior.

It is now possible to configure the behavior choosing among 4 different options:

  • NODIFUSR: The default as described above.
  • DIFUSR: Locks on co-files are considered as acquired from a different connection, so the lock on R issued with co-file number 10 will fail.
  • SAMUSR_M: Locks on record R on co-files are considered as the same lock acquired on the same file, so lock on R issued with co-file number 10 succeeds. As soon as the lock is released in one of the co-files that successfully requested the lock, the lock is released. Therefore, before acquiring the lock on R using file number 10, the lock can be released only using file number 5, but after acquiring the lock on R using file number 10, the lock can be released either by using file number 5 or 10.
  • SAMUSR_1: Locks on record R on co-files are considered as the same lock acquired on the same file, so lock on R issued with co-file number 10 succeeds. As soon as the lock is released in one of the co-files (whether or not the lock was requested using the co-file) the lock is released. Therefore, even before acquiring the lock on R using file number 10 the lock can be released either by using file number 5 or 10.

Recursive locks are not supported for co-files. An attempt to open a co-file when recursive locks are pending on the underlying file will fail with the error MUOP_RCR (998). An attempt to issue a lock on a co-file with the ctLK_RECR bit set in the lock mode will fail with the error MLOK_ERR (999).

Read locks behave in a manner consistent with write locks. The notable issues are:

  1. With DIFUSR, read locks can be issued for different co-files; and unlocking one co-file's read lock does not remove the read lock from any other co-files that requested the read lock.
  2. With DIFUSR, a read lock on a co-file cannot be promoted to a write lock if other co-files have read locks; a non-blocking write lock will fail with DLOK_ERR (42) and a blocking write lock will fail with DEAD_ERR (86).
  3. With SAMUSR_*, read locks can be issued for different co-files, and unlocking one co-file read lock unlocks all the co-file read locks.
  4. With SAMUSR_*, read locks can be promoted to write locks as long as no other threads have also acquired read locks.
  5. With SAMUSR_1, a read lock on a co-file can be unlocked using another co-file's file number even if no lock has been issued using the other co-file number.

The system-level default can be controlled by using one of the following configuration keywords which sets the behavior accordingly to their names.

  • COMPATIBILITY MULTIOPN_DIFUSR
  • COMPATIBILITY MULTIOPN_SAMUSR_M
  • COMPATIBILITY MULTIOPN_SAMUSR_1

A connection can override the system-level default for all open instances of a file by calling:

PUTHDR(datno, mode, ctMULTIOPNhdr)

Where mode is one of the following:

  • ctMULTIOPNnodifusr
  • ctMULTIOPNdifusr
  • ctMULTIOPNsamusr_M
  • ctMULTIOPNsamusr_1

If no PUTHDR call is made, the system-level default is used for that connection's instances of the file. When a file is opened, if that connection already has the file open, the newly opened file inherits the MULTIOPN setting of the already-open file instance. An attempt to change the setting so that one instance of the file would be inconsistent with the others will fail with error MOFL_ERR. A file's MULTIOPN state can only be changed if it is the first open instance of the file and it has no pending locks.

TOCIndex