In global regions, the system locks entries
and the region during updates. You can also explicitly lock the region and its entries as
needed by your application. Locking includes system settings that help you optimize
performance and locking behavior between your members.
In regions with global scope, locking helps ensure cache consistency.
Locking of regions and entries is done in two ways:
- Implicit. GemFire
automatically locks global regions and their data entries during most
operations. Region invalidation and destruction do not acquire locks.
- Explicit. You can use the
API to explicitly lock the region and its entries. Do this to guarantee
atomicity in tasks with multi-step distributed operations. The
return instances of java.util.concurrent.locks.Lock for a
region and a specified key.
Note: You must use the Region
API to lock regions and region entries. Do not use the
DistributedLockService in the
com.gemstone.gemfire.distributed package. That
service is available only for locking in arbitrary distributed
applications. It is not compatible with the Region
Getting a lock on a region or entry is a two-step process of getting a lock instance
for the entity and then using the instance to set the lock. Once you have the lock,
you hold it for your operations, then release it for someone else to use. You can
set limits on the time spent waiting to get a lock and the time spent holding it.
Both implicit and explicit locking operations are affected by the timeouts:
- The lock timeout limits the wait to
get a lock. The cache attribute lock-timeout governs
implicit lock requests. For explicit locking, specify the wait time through
your calls to the instance of
java.util.concurrent.locks.Lock returned from the
Region API. You can wait a specific amount of time,
return immediately either with or without the lock, or wait indefinitely.
- The lock lease limits how long a
lock can be held before it is automatically released. A timed lock allows
the application to recover when a member fails to release an obtained lock
within the lease time. For all locking, this timeout is set with the cache
Optimize Locking Performance
For each global region, one of the members with the region defined will be assigned
the job of lock grantor. The lock grantor runs the lock service that receives lock
requests from system members, queues them as needed, and grants them in the order
The lock grantor is at a slight advantage over other members as it is the only one
that does not have to send a message to request a lock. The grantor’s requests cost
the least for the same reason. Thus, you can optimize locking in a region by
assigning lock grantor status to the member that acquires the most locks. This may
be the member that performs the most puts and thus requires the most implicit locks
or this may be the member that performs many explicit locks.
The lock grantor is assigned as follows:
- Any member with the region defined
that requests lock grantor status is assigned it. Thus at any time, the most
recent member to make the request is the lock grantor.
- If no member requests lock grantor
status for a region, or if the current lock grantor goes away, the system
assigns a lock grantor from the members that have the region defined in
You can request lock grantor status:
- At region creation through the
is-lock-grantor attribute. You can retrieve this
attribute through the region method, getAttributes, to see
whether you requested to be lock grantor for the region.
is-lock-grantor attribute does not change after
- After region creation through the
region becomeLockGrantor method. Changing lock grantors
should be done with care, however, as doing so takes cycles from other
operations. In particular, be careful to avoid creating a situation where
you have members vying for lock grantor status.
These two examples show entry locking and unlocking. Note how the entry’s
object is obtained and then its lock method invoked to
actually set the lock. The example program stores the entry lock information in a
hash table for future reference.
/* Lock a data entry */
HashMap lockedItemsMap = new HashMap();
String entryKey = ...
Lock lock = this.currRegion.getDistributedLock(entryKey);
/* Unlock a data entry */
String entryKey = ...
Lock lock = (Lock) lockedItemsMap.remove(name);