在Azure缓存中处理悲观并发的最佳方法是什么?
我是azure缓存新手,面临一个问题 我将首先简要介绍该场景。我们正在使用在Azure缓存中处理悲观并发的最佳方法是什么?,azure,pessimistic-locking,Azure,Pessimistic Locking,我是azure缓存新手,面临一个问题 我将首先简要介绍该场景。我们正在使用sqlazure作为应用程序的数据库。为了避免延迟问题和限制问题,我们正在使用Azure缓存(web角色上的同一位置缓存)。通过使用Azure缓存,我们只从数据库中获取一次数据,并将其保存在缓存中以供进一步使用 因为我们使用的是缓存数据,所以这里的挑战是,无论何时执行任何DML操作,都要始终保持SQL Azure DB和Azure缓存之间的数据同步。我们首先更新数据库,如果更新成功,则使缓存数据无效。这种方法适用于正常场景
sqlazure
作为应用程序的数据库。为了避免延迟问题和限制问题,我们正在使用Azure缓存(web角色上的同一位置缓存)。通过使用Azure缓存,我们只从数据库中获取一次数据,并将其保存在缓存中以供进一步使用
因为我们使用的是缓存数据,所以这里的挑战是,无论何时执行任何DML操作,都要始终保持SQL Azure DB和Azure缓存之间的数据同步。我们首先更新数据库,如果更新成功,则使缓存数据无效。这种方法适用于正常场景。
然而,由于并发用户在工作和执行更新,似乎存在一个问题。我们在更新缓存中的数据时使用悲观并发模型。在这里,我们使用暂时重试策略来确保重试尝试(假设5次,固定间隔为1秒)
示例代码如下所示:
Microsoft.Practices.TransientFaultHandling.RetryPolicy cacheRetryPolicy =
GetAzureCacheRetryPolicy();
cacheRetryPolicy.Retrying += TransientRetryManager.OnRetrying;
DataCacheLockHandle handle = null;
cacheRetryPolicy.ExecuteAction(() =>
{
try
{
object obj = cache.GetAndLock(key, TimeSpan.FromSeconds(1), out handle);
cache.PutAndUnlock(key, value, handle, expirationTime.Value, tags);
}
catch (DataCacheException ex)
{
if (ex.ErrorCode == DataCacheErrorCode.KeyDoesNotExist)
{
cache.Put(key, value, expirationTime.Value, tags);
}
else
{
//This means wait till the cache is released.
//Throwing from here will allow to retry with Transient
//handling retry policy.
throw ex;
}
}
}
在这里,如果等待次数(比如说6次)超过重试尝试次数(即在我们的情况下为5次)。当第6次轮到它时,重试尝试已经结束,因此具有最新更新的第6次等待将无法在缓存中更新它
有一种方法可以克服此问题,即在获取缓存密钥锁定时,在errorcode
被objectlocked
锁定的情况下,将所有等待排队
有谁能提出处理这个案件的最佳方法吗 若我并没有错的话,缓存的结果并没有在DB中保存最新的数据
--------------------------------------------------------------------------------
This could happen in following Scenario
--------------------------------------------------------------------------------
Time User 1 User 2
1 Updates DB data from A to B Idle
4 Adding data to cache Updates DB data from B to C
5 Still adding to cache Adding data to cache
7 Still adding to cache caching is done
9 Still adding to cache current data is C
10 caching is done
11 current data is B (but it should be C)
So what we have done is
-----------------------------------------------------------------------------------
Time User 1 User 2
-----------------------------------------------------------------------------------
1 Updates DB data from A to B Idle
4 Adding data to cache Updates DB data from B to C
5 still adding to cache Adding data to cache
7 Still adding to cache caching is done with last modified date
9 Still adding to cache current data is C
10 found that cached date is greater than the current
11 skips caching