Freigeben über


Windows Azure Cache - Pessimistic Concurrency Model

In this model, client application acquires a lock before performing the operations. In order to acquire a lock on an object, you need a lock handle of DataCacheLockHandle . The same lock handle is needed to unlock the object. It’s important to remember that Locked objects in the cache can still be replaced by any cache client with the Put method. Cache-enabled applications are responsible for consistently using PutAndUnlock for items that use the pessimistic concurrency model. In case the client application ends before freeing a locked object, time-outs are provided to release the locks.

Here is a list of methods that you can use to lock and unlock an object:

GetAndLock
Returns and locks the cached object (if present). Other GetAndLock method calls on the same object fail as long as the lock is valid. Regular Get method calls are not blocked and always access the latest version of the cached object.

PutAndUnlock
Updates the locked object and then releases the lock. The lock handle obtained from GetAndLock is a required parameter and must match the lock handle of the locked object to succeed.

Unlock
Explicitly unlocks a cached object, provided that the lock handle parameter matches that of the locked object. Unlock also supports extending the expiration of the current item to help prevent it from expiring as soon as it is unlocked (if it is unlocked past its expiration time).

 

Sample Code

// vars
DataCacheFactory cacheFactory = new DataCacheFactory();
DataCacheLockHandle lockHandle;
DataCache cacheInstance;
TimeSpan timeout = TimeSpan.FromMinutes(1);
string strKey = "Employee";

// Make sure the key exist in Cache, before you acquire a lock
cacheInstance.Add(strKey, "value version 1.0");

// This will acquire a lock with a Lock timeout of 1 minute
object objReturnValue = (string)cacheInstance.GetAndLock(strKey, timeout, out lockHandle);

// This will put the value back in Cache and release the lock
objReturnValue = "value version 2.0";
cacheInstance.PutAndUnlock(strKey, objReturnValue, lockHandle);

 

So what happens when you try to acquire a lock when the object is already locked? Azure will simply throw an error.

ErrorCode<ERRCA0011>:SubStatus<ES0001>:Object being referred to is currently locked, and cannot be accessed until it is unlocked by the locking client. Please retry later.
  Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

 Exception Details: Microsoft.ApplicationServer.Caching.DataCacheException: ErrorCode<ERRCA0011>:SubStatus<ES0001>:Object being referred to is currently locked, and cannot be accessed until it is unlocked by the locking client. Please retry later.

[DataCacheException: ErrorCode<ERRCA0011>:SubStatus<ES0001>:Object being referred to is currently locked, and cannot be accessed until it is unlocked by the locking client. Please retry later.]
   Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody) +693
   Microsoft.ApplicationServer.Caching.DataCache.ExecuteAPI(RequestBody reqMsg, IMonitoringListener listener) +107
   Microsoft.ApplicationServer.Caching.DataCache.InternalGetAndLock(String key, TimeSpan timeout, DataCacheLockHandle& lockHandle, String region, Boolean lockKey, IMonitoringListener listener) +590
   Microsoft.ApplicationServer.Caching.<>c__DisplayClass78.<GetAndLock>b__77() +436
   Microsoft.ApplicationServer.Caching.EmptyListener.Microsoft.ApplicationServer.Caching.IMonitoringListener.Listen(Func`1 innerDelegate) +57
   Microsoft.ApplicationServer.Caching.DataCache.GetAndLock(String key, TimeSpan timeout, DataCacheLockHandle& lockHandle) +369
   WebRole1._Default.Button1_Click(Object sender, EventArgs e) in d:\xxx-xxx-xxxxx\Default.aspx.cs:49
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +155
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3804