Locks

A lock is used to ensure exclusivity of a series of map operations in a persistence service.

If a series of client map API calls using a lock completes without an exception, then an application may be assured that no other writer using the same lock concurrently modified a map in the persistence service, and that the modifications will be visible to future readers using the same lock.

If a map API call using a lock fails, then nothing may be assumed about the result of that operation, and the lock must be returned or destroyed before trying again.

A typical use is to implement atomic test-and-set on a particular row of a map. See the sample program tibftlmap-lock.

Lock Name

When a program creates a lock object, it assigns a lock name. A persistence cluster may contain many locks, each with a unique name. Two lock objects with the same name represent the same lock, so two or more application processes can use the lock to cooperate.

Two lock objects with different names do not interact with each other or block each other in any way.

Programmers choose the name of a lock to indicate the purpose of the lock: for example, ServerStatusMapLock might lock an entire map that stores the states of server hardware within an enterprise, while BlueLock might lock the row of that map that describes the state of the server named Blue.

Methods of Lock Objects

API methods can do these operations:

  • Create a lock.

  • Return (that is, release) a lock that the process holds.

  • Steal a lock that another process holds.

  • Destroy a lock object to reclaim resources.

Methods with Locks and without Locks: Effective Use

Map operations are available in two forms: with lock and without lock. Methods that take a lock argument respect the state of that lock: that is, if another process holds the lock, then one of two outcomes will occur:

  • If program code specified a retry duration when creating the lock, the call will block until the retry duration elapses. If the lock is returned by the other process before the retry duration elapses, the call can proceed. Otherwise, the call will raise an exception, and the requested operation (for example, get or set a key) will not occur.

  • If program code did not specify a retry duration when creating the lock, the call will raise an exception, and the requested operation (for example, get or set a key) will not occur.

However, methods that do not take a lock argument do not respect the state of any lock: even if another process holds a lock for the map or for the key row, the method does not test the lock, and completes its map operation.

For locks to effectively prevent interference, all your application processes must access the map using only methods with locks. Lock objects with different names do not interact with each other or block each other in any way.

Pattern for Programming with Locks

  1. Create a lock object.

  2. Call one or more methods with that lock.

    A program can call many methods with that lock, even within a loop, as with a map iterator.

    While the process still holds the lock, these methods succeed. Otherwise they throw an exception. If an exception occurs, program code must return the lock before making another API call with the lock. This is necessary in order to clear the lock’s broken state, and to make client code recognize that its view of the map may be out of date. See Breaking a Lock.

  3. Return the lock.

Breaking a Lock

If a client program holds a lock, the lock can be lost (broken) under the following conditions:

  • The client program disconnects from the persistence cluster due to a network interruption.

  • Another client program steals the lock. See below.

When either condition occurs, the ongoing or next API call with the lock will raise an exception. This indicates that the program’s state is no longer valid (for example, another program may have acquired the lock and made changes to the map). Program code must return the lock, clearing its state, before attempting further API calls with the lock.

Locks and Stores

When a process acquires a lock, it associates the lock with a specific persistence cluster. When a process releases a lock, it cancels the association, making the lock available to use with any persistence cluster.

While a lock is associated with one persistence cluster, it is illegal to use it in a map operation on any other persistence cluster. Method calls that violate this restriction throw an exception.

Steal: Only to Circumvent a Blocked Lock

If a program process, A, holds a lock and does not return it in a timely fashion, the corresponding map or row remains inaccessible to other process that request that lock. To circumvent this blockage, another program process, B, can steal the lock.

When process A subsequently uses that lock in a map method call, the method throws an exception.