Locking in Global Regions
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. Geode 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
Region
methodsorg.apache.geode.cache.Region.getDistributedLock
andorg.apache.geode.cache.Region.getRegionDistributedLock
return instances ofjava.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 theDistributedLockService
in theorg.apache.geode.distributed
package. That service is available only for locking in arbitrary distributed applications. It is not compatible with theRegion
locking methods.
Lock Timeouts
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 ofjava.util.concurrent.locks.Lock
returned from theRegion
API. You can wait a specific amount of time, return immediately either with or without the lock, or wait indefinitely.<cache lock-timeout="60"> </cache>
gfsh:
gfsh>alter runtime --lock-timeout=60
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 attribute
lock-lease
.<cache lock-lease="120"> </cache>
gfsh:
gfsh>alter runtime --lock-lease=120
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 received.
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 their caches.
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. Note: Theis-lock-grantor
attribute does not change after region creation.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.
Examples
These two examples show entry locking and unlocking. Note how the entry’s Lock
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 = ...
if (!lockedItemsMap.containsKey(entryKey))
{
Lock lock = this.currRegion.getDistributedLock(entryKey);
lock.lock();
lockedItemsMap.put(name, lock);
}
...
/* Unlock a data entry */
String entryKey = ...
if (lockedItemsMap.containsKey(entryKey))
{
Lock lock = (Lock) lockedItemsMap.remove(name);
lock.unlock();
}