Pessimistic Locking (Exclusive Locking)
NCache provides a locking mechanism that exclusively locks the cached data. In
this mechanism, you have to use APIs with lock handle. A lock handle
is a
handle associated with every locked item in the cache, which is returned by
locking API. A locked item can be fetched/updated or unlocked only when its lock
handle is provided at API level. However, you should do this with care to avoid
data integrity issues.
Lock Expiration: You can also specify lock timeout while locking a cached item. The lock timeout is the time interval after which the lock will be automatically released if no explicit call is made for releasing the lock during the time out interval. This will prevent your data from being locked for an infinite amount of time.
This locking mechanism is useful in situations where you want to exclusively lock your cache data to prevent multiple clients from updating it simultaneously.
Forceful release of locks: Situations can arise in distributed environments when an application which acquired the lock on a cache item terminates abruptly. In such a situation you would like to release all locks acquired by such an application. NCache provides an unlock API, which releases the cache item lock forcefully.
Special Consideration while using API Locking
NCache provides a set of APIs with and without lock handles to fetch/update the cache item. API's without a lock handle ignore item locking. So you should use all locking APIs for data manipulation. For example, if an item is locked and you make an update API call which does not take the lock handle as input parameter, then the item will be updated in the cache irrespective of its locking state. Therefore, when using a locking feature, you should only use API calls which take lock handles as parameters. API's which do not take lock handles can be used but should be done so with a lot of care so that it does not affect data integrity.
Note
In case of eviction/expiration, NCache ignores locks which mean that a locked item can be removed as a result of expiration or eviction.
Lock Cache Data
A lockHandle is associated with an item to ensure that the particular item remains inaccessible throughout the cache. Two primary properties lockId and lockdate are used to ensure the appropriate behavior of locking while performing various cache operations.
NCache provides method calls exclusively for locking as well as numerous overloads that manipulate the locking mechanism.
To utilize the APIs, include the following namespace in your application:
Alachisoft.NCache.Web.Caching
.
Locking an Item Explicitly
You can explicitly acquire lock on an item before performing any operation. Lock
method requires a TimeSpan
to lock an item for a specified time. However, if
you do not want the acquired lock to expire simply specify a new TimeSpan
.
The Lock
method used in this example associates a lockHandle with a key.
Kindly ensure that the single LockHandle
is associated with a single key.
Release the lock before reusing the handle; otherwise it might lead to
inconsistency of behavior.
//create a new lock Handle
LockHandle lockHandle = new LockHandle();
string key = "Product:1001";
try
{
// Specifiying the time span of 10 sec for which the item remains locked
bool locked = cache.Lock(key, new TimeSpan(0, 0, 10), out lockHandle);
}
catch (OperationFailedException ex)
{
// handle exception
}
Locking Item during Fetch Operation
An item can be locked during the process of its retrieval from the cache. This means that the item will be inaccessible for others unless you release it. In case of mismatch of key, null value is returned.
In this example you need to specify a key and a lockHandle for the key to fetch the cached object and lock it. You need to specify “true” if you need to acquire the lock.
LockHandle lockHandle = new LockHandle();
//Specify time span of 10 sec for which the item remains locked
TimeSpan lockSpan = new TimeSpan(0, 0, 10);
string key = "Product:1001";
try
{
object result = cache.Get(key, lockSpan, ref lockHandle, true);
if (result != null)
{
if (result is Product)
{
Product product = (Product)result;
}
}
}
catch (OperationFailedException ex)
{
// handle exception
}
Locking with Expiration
If you need to acquire a lock for a certain period of time, specify the time period. NCache would lock the item for that specified time.
LockHandle lockHandle = new LockHandle();
//Specify time span of 10 sec for which the item remains locked
TimeSpan lockSpan = new TimeSpan(0, 0, 10);
string key = "Product:1001";
try
{
bool lockAcquired = cache.Lock(key, lockSpan, out lockHandle);
//Verify that the lock is released automatically after this time period.
}
catch (OperationFailedException ex)
{
// handle exception
}
Releasing Lock with Update Operation
While updating an item, you can release the lock allowing others to use the cached data. In order to successfully release the locked item, you will need to specify the lockHandle initially used to lock the item.
Product updatedProduct = new Product();
updatedProduct.ProductID = 1001;
updatedProduct.ProductName = "Chai";
updatedProduct.Category = 4;
string key = "Product" + updatedProduct.ProductID;
LockHandle lockHandle = new LockHandle();
try
{
// lock exisiting item for the time span of 30 seconds
bool locked = cache.Lock(key, TimeSpan.FromSeconds(30), out lockHandle);
if (locked)
{
cache.Insert(key, new CacheItem(updatedProduct), lockHandle, true);
}
}
catch (OperationFailedException ex)
{
// handle exception
}
Releasing Lock Explicitly
In order to release lock explicitly on a previously locked cached item; you will need to specify the lockHandle used to lock the key.
LockHandle lockHandle = new LockHandle();
string key = "Product:1001";
try
{
// lock an existing item and save the lockHandle for 10 seconds
bool locked = cache.Lock(key, new TimeSpan(0, 0, 10), out lockHandle);
if (locked)
{
// unlock locked item using saved LockHandle
cache.Unlock(key, lockHandle);
}
}
catch (OperationFailedException ex)
{
// handle exception
}
Warning
NCache will ignore the locks if other overloads of Get
, Insert
and Remove
methods are called.
Indexing Object Attributes for Search
Note
This feature is only available in NCache Enterprise Edition.
NCache requires all searchable attributes to be indexed. This is because, without indexing, NCache would have to traverse the entire cache in order to find items. This could be very costly operation with potential of slowing down the entire cache processes.
NCache provides its own indexing mechanism. The user can select objects in .NET assemblies that he/she wants to index. NCache uses .NET Reflection to extract data from the indexed attributes and builds its internal index. When data to be indexed is inserted in cache, NCache creates an index tree and adds those associated keys in them. These indexes then later on contain all the keys from cache associated to them. When cache is queried, NCache uses these indexes to quickly find the desired objects and returns all related keys or items.
Indexing Attributes of the Cached Item
NCache Manager provides a user friendly interface for defining indexes. The following example demonstrates procedure of defining indexes on attributes.
Suppose that cache contains Product object where the definition of Product is as below:
[Serializable]
public class Product
{
private int productID;
private string productName;
//...
/// <summary>
/// Get/Set the ProductID.
/// </summary>
public int ProductID
{
get { return productID; }
set { productID = value; }
}
/// <summary>
/// Get/Set the Product name.
/// </summary>
public string ProductName
{
get { return productName; }
set { productName = value; }
}
}