Product Documentation

FairCom ISAM for C

Previous Topic

Next Topic

Recursive Locking Support

Introduction to Recursive Locks

FairCom introduces an advanced locking feature of Recursive Locks. A recursive lock is a lock applied to a record by a user already owning the same lock on the same record, and such an additional lock request is “counted.” For middle code that does not have a means to know the context of what has already been done to a record, the recursive lock offers the ability to lock and unlock a record without worrying whether the unlock will strip a needed lock obtained outside the current c-tree context.

Recursive locks are typically useful for an application that must make LOCK and UNLOCK calls without knowledge of already existing locks on the same record by the same application.

Consider a user making more than one lock call for the same record. With the previous c-tree locking mechanism, this would have no effect on the record’s lock state. For instance, assume the following sequence of calls is from a single user (and for simplicity we assume the file is not under transaction control):

LOCK Record A

LOCK Record A

UNLOCK Record A

UNLOCK Record A

The second LOCK would return no error yet have no effect. However, the first UNLOCK would release the lock and the second UNLOCK would return an error.

Modifying the above example, we illustrate the effect with Recursive Locks enabled:

RECURSIVE LOCK Record A

RECURSIVE LOCK Record A

RECURSIVE UNLOCK Record A

RECURSIVE UNLOCK Record A

Here, the second RECURSIVE LOCK returns no error, and the recursive lock count on the record is incremented to 2. The first recursive UNLOCK will not release the lock, but simply decrement the recursive lock count to 1, and return NO_ERROR. The second recursive UNLOCK will then release the lock and return success (NO_ERROR).

Recursive Locking Mode

Recursive locks must be requested explicitly through a lock mode. An application that does not explicitly request recursive locks will behave the same as it did without recursive lock support. The following API calls support OR-ing in a recursive lock mode bit, ctLK_RECR: TRANBEG(), TRANEND(), LKISAM() and LOKREC(). For example, LKISAM(ctENABLE_BLK | ctLK_RECR) would request blocking, recursive write locks on each record accessed at the ISAM level.

A TRANRST() called to return to save point N causes recursive lock and unlock calls made since save point N to be undone. For example:

TRANBEG(ctENABLE | ctLK_RECR)

LOCK Record A

SAVEPOINT #1

LOCK Record A /* increase recursive count to 2 */

TRANRST to savepoint 1

results in record A to have a recursive lock with a count of 1.

Mixing Recursive and Non-recursive Locks

While it is not recommended, mixing recursive and non-recursive locks has the following effects:

  1. If an existing non-recursive lock is followed by a recursive lock, then the existing lock is promoted to a recursive lock with a recursive lock count of 2.
  2. If a recursive lock is followed by a non-recursive lock, the non-recursive locks has no effect and returns NO_ERROR.
  3. If a non-recursive unlock call is made to a recursive lock, it causes the lock to be released (ignoring the recursive status).

Mixing Recursive Read and Write Locks

Scenario A: A user holds recursive write lock(s) on Record A and then issues a recursive read lock request on Record A: the recursive read lock request returns success (NO_ERROR), but the lock remains a write lock with its recursive lock count incremented. This behavior is necessary since the existing recursive write locks cannot be arbitrarily changed to a read lock since they are still being held.

Scenario B: A user holds recursive read lock(s) on Record A and then issues a recursive write lock request on Record A: the recursive write lock request returns success (NO_ERROR) and the lock is changed to a write lock if no other read locks are being held by other users, and the recursive count is incremented; or the write lock returns failure if other users do hold read locks on Record A, and the existing read lock(s) for the user remains and the recursive count is unchanged.

Due to the existing nature of the system lock tables within FairCom DB, there is virtually no extra overhead to apply the recursive lock count.

TOCIndex