Skip to main content

Incremental Locking and Unlocking

Incremental Locking and Unlocking

Incremental locking permits you to apply the same lock multiple times: to increment the lock. An incremented lock has a lock count of > 1. Your process can subsequently increment and decrement this lock count. The lock is released when the lock count decrements to 0. No other process can acquire the lock until the lock count decrements to 0. The lock table maintains separate lock counts for exclusive locks and shared locks, and for escalating and non-escalating locks of each type. The maximum incremental lock count is 32,766. Attempting to exceed this maximum lock count results in a <MAX LOCKS> error.

You can increment a lock as follows:

  • Plus sign: Specify multiple lock operations on the same lock name with the plus sign lock operation indicator. For example: LOCK +^a(1) LOCK +^a(1) LOCK +^a(1) or LOCK +^a(1),+^a(1),+^a(1) or LOCK +(^a(1),^a(1),^a(1)). All of these would result in a lock table ModeCount of Exclusive/3. Using the plus sign is the recommended way to increment a lock.

  • No sign: It is possible to increment a lock without using the plus sign lock operation indicator by specifying an atomic operation performing multiple locks. For example, LOCK (^a(1),^a(1),^a(1)) unlocks all prior locks and incrementally locks ^a(1) three times. This too would result in a lock table ModeCount of Exclusive/3. While this syntax works, it is not recommended.

Unlocking an incremented lock when not in a transaction simply decrements the lock count. Unlocking an incremented lock while in a transaction has the following default behavior:

  • Decrementing Unlocks: each decrementing unlock immediately release the incremental unlock until the lock count is 1. By default, the final unlock puts the lock in delock state, deferring release of the lock to the end of the transaction. This is always the case when you delock with the minus sign lock operation indicator, whether or not the operation is atomic. For example: LOCK -^a(1) LOCK -^a(1) LOCK -^a(1) or LOCK -^a(1),-^a(1),-^a(1) or LOCK -(^a(1),^a(1),^a(1)). All of these begin with a lock table ModeCount of Exclusive/3 and end with Exclusive->Delock.

  • Unlocking Prior Resources: an operation that unlocks all prior resources immediately puts an incremented lock into a delock state until the end of the transaction. For example, either LOCK x(3) (lock with no lock operation indicator) or an argumentless LOCK would have the following effect: the incremented lock would begin with a lock table ModeCount of Exclusive/3 and end with Exclusive/3->Delock.

Note that separate lock counts are maintained for the same lock as an Exclusive lock, a Shared lock, a Exclusive escalating lock and a Shared escalating lock. In the following example, the first unlock decrements four separate lock counts for lock ^a(1) by 1. The second unlock must specify all four of the ^a(1) locks to remove them. The HANG commands give you time to check the lock’s ModeCount in the Lock Table.

   LOCK +(^a(1),^a(1)#"E",^a(1)#"S",^a(1)#"SE")
   LOCK +(^a(1),^a(1)#"E",^a(1)#"S",^a(1)#"SE")
   HANG 10
   LOCK -(^a(1),^a(1)#"E",^a(1)#"S",^a(1)#"SE")
   HANG 10
   LOCK -(^a(1),^a(1)#"E",^a(1)#"S",^a(1)#"SE")

If you attempt to unlock a lock name that has no current locks applied, no operation is performed and no error is returned.

Automatic Unlock

When a process terminates, InterSystems IRIS performs an implicit argumentless LOCK to clear all locks that were applied by the process. It removes both held locks and lock wait requests.

FeedbackOpens in a new tab