我正在服务器端使用Azure Shared Caching构建缓存层,以减少对数据库的请求并使运行速度更快(希望能如此)。但我卡在了如何让整个过程线程安全上。我似乎找不到一个可靠和可用的方法来锁定DataCache中的键。我需要一种在存储任何内容之前就可以预先锁定键的方法,以便我能够添加值而无需担心另一个线程同时执行相同操作的风险。
迄今为止,我一直在专注于悲观锁定,因为这是我认为最具有线程安全性的方式,我希望确保我所工作的内容被锁定。
我已经知道,如果我要使用悲观锁定,那么我应该只使用与其相关的方法。混合使用其他方法将破坏整个锁定机制。(来源:http://go4answers.webhost4life.com/Example/datacacheput-unlocking-key-77158.aspx)
“GetAndLock”在我尝试获取不在缓存中的东西时会抛出异常。同时,我的唯一添加内容到缓存的方法是“PutAndUnlock”,但只有成功执行“GetAndUnlock”后才能使用它。
实际上,不可能向缓存中添加任何新内容,只能替换已经存在的内容(这些内容可能为空)。
所以,在“GetAndLock”抛出没有内容时的异常情况下,我似乎被迫使用乐观的“Put”。根据我阅读的内容,但是,乐观的“Put”会破坏使用“GetAndLock”获得的任何现有锁定,这将破坏线程安全的整个尝试。
迄今为止,我一直在专注于悲观锁定,因为这是我认为最具有线程安全性的方式,我希望确保我所工作的内容被锁定。
我已经知道,如果我要使用悲观锁定,那么我应该只使用与其相关的方法。混合使用其他方法将破坏整个锁定机制。(来源:http://go4answers.webhost4life.com/Example/datacacheput-unlocking-key-77158.aspx)
So basicly I only have access to these methods:
value GetAndLock(key, out DataCacheLockHandle);
void PutAndUnlock(key, value, DataCacheLockHandle);
void Unlock(key, DataCacheLockHandle);
“GetAndLock”在我尝试获取不在缓存中的东西时会抛出异常。同时,我的唯一添加内容到缓存的方法是“PutAndUnlock”,但只有成功执行“GetAndUnlock”后才能使用它。
实际上,不可能向缓存中添加任何新内容,只能替换已经存在的内容(这些内容可能为空)。
所以,在“GetAndLock”抛出没有内容时的异常情况下,我似乎被迫使用乐观的“Put”。根据我阅读的内容,但是,乐观的“Put”会破坏使用“GetAndLock”获得的任何现有锁定,这将破坏线程安全的整个尝试。
Example plan:
1. Try to GetAndLock
2. In case of nothing there exception:
- Put a dummy item on the key.
- GetAndLock again.
3. We have a lock, do computations, query database etc
4. PutAndUnlock the computed value
One of probably several ways it would screw up:
Thread1: Tries to GetAndLock, gets nothing there exception
Thread2: Tries to GetAndLock, gets nothing there exception
Thread1: Put a dummy item on the key
Thread1: GetAndLock again, lock achieved
Thread2: Put a dummy item on the key (destroying Thread1:s lock)
Thread2: GetAndLock again, lock achieved
Thread1: We think we have a lock, do computations, query database etc
Thread2: We have a lock, do computations, query database etc
Thread1: PutAndUnlock the computed value (will this throw an exception?)
Thread2: PutAndUnlock the computed value
基本上,两个线程可能会同时向同一个键写入不同的内容,而忽略它们都认为拥有的锁。
我唯一的结论是,DataCache的悲观锁定功能不完整且完全无法使用。我是否遗漏了什么?有没有解决这个问题的方法?
我需要的只是在存储任何内容之前就预先锁定键的方法。
forceLock
的参数,MSDN上解释说:如果forceLock
为true,则无论缓存中是否存在键值对,都会锁定该键。这难道不能帮助您在状态不存在的情况下锁定键吗? - psulek