Apache Geode CHANGELOG

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:

  1. Implicit. Geode automatically locks global regions and their data entries during most operations. Region invalidation and destruction do not acquire locks.
  2. 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 methods org.apache.geode.cache.Region.getDistributedLock and org.apache.geode.cache.Region.getRegionDistributedLock 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 org.apache.geode.distributed package. That service is available only for locking in arbitrary distributed applications. It is not compatible with the Region 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 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.

    <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:

  1. 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: The is-lock-grantor attribute does not change after region creation.

  2. 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();
  }