并发模型(AppFabric 1.1 缓存)
Microsoft AppFabric 1.1 for Windows Server 体系结构允许任何缓存客户端公开访问任何缓存的数据(如果这些客户端具有适当的网络访问权限和配置设置)。这对于安全性和并发性是一大挑战。
为了降低安全风险,所有缓存客户端、缓存服务器和主要数据源服务器应是同一域的成员,且应部署在防火墙外围内。还强烈建议您确保缓存客户端上应用程序配置文件的安全。
为了帮助您的应用程序处理并发问题,AppFabric 支持乐观并发和悲观并发模型。要了解与这两个模型保持一致的方法,请参阅并发方法。
乐观并发模型
在乐观并发模型中,缓存对象的更新不进行锁定。但当缓存客户端从缓存获得对象时,它还获得并存储该对象的当前版本。当需要进行更新时,缓存客户端会将对象新值与已存储的版本对象一起发送。仅当发送的版本与缓存中对象的当前版本匹配时,系统才会更新对象。对象的每次更新都会更改其版本号,这可以防止更新覆盖其他人的更改。
本主题中的示例介绍乐观并发模式如何维护数据的一致性。
示例
在本示例中,两个单独应用程序服务器上的两个缓存客户端(cacheClientA
和 cacheClientB
)尝试更新同一个名为 RadioInventory
的缓存对象。
时间零点:两个客户端都检索同一个对象
在时间零点 (T0),两个客户端都实例化 DataCacheItem 类,以捕获其要更新的缓存对象,以及与已该缓存对象关联的其他信息(例如,版本和标记信息)。这将显示在以下图表和代码示例中。
'cacheClientA pulls the FM radio inventory from cache
Dim clientACacheFactory As DataCacheFactory = New DataCacheFactory()
Dim cacheClientA As DataCache = _
clientACacheFactory.GetCache("catalog")
Dim radioInventoryA As DataCacheItem = _
cacheClientA.GetCacheItem("RadioInventory", "electronics")
'cacheClientB pulls the same FM radio inventory from cache
Dim clientBCacheFactory As DataCacheFactory = New DataCacheFactory()
Dim cacheClientB As DataCache = _
clientBCacheFactory.GetCache("catalog")
Dim radioInventoryB As DataCacheItem = _
cacheClientA.GetCacheItem("RadioInventory", "electronics")
//cacheClientA pulls the FM radio inventory from cache
DataCacheFactory clientACacheFactory = new DataCacheFactory();
DataCache cacheClientA = clientACacheFactory.GetCache("catalog");
DataCacheItem radioInventoryA =
cacheClientA.GetCacheItem("RadioInventory","electronics");
//cacheClientB pulls the same FM radio inventory from cache
DataCacheFactory clientBCacheFactory = new DataCacheFactory();
DataCache cacheClientB = clientBCacheFactory.GetCache("catalog");
DataCacheItem radioInventoryB=
cacheClientA.GetCacheItem("RadioInventory", "electronics");
备注
虽然此示例通过使用 GetCacheItem 方法获得版本信息来检索 DataCacheItem 对象,但它还可以使用 Get 方法获得与检索到的缓存项目关联的 DataCacheItemVersion 对象。
时间 1:首次更新成功
在时间 1(T1),cacheClientA
更新具有新值的缓存对象 RadioInventory
。当 cacheClientA
执行 Put 方法时,与 RadioInventory
缓存项目相关联的版本会递增。此时,cacheClientB
具有过期缓存项目。这将显示在以下图表和代码示例中。
'at time T1, cacheClientA updates the FM radio inventory
Dim newRadioInventoryA As Integer = 155
cacheClientA.Put("RadioInventory", newRadioInventoryA, _
radioInventoryA.Version, "electronics")
//at time T1, cacheClientA updates the FM radio inventory
int newRadioInventoryA = 155;
cacheClientA.Put("RadioInventory", newRadioInventoryA,
radioInventoryA.Version,"electronics");
时间 2:第二次更新失败
在时间 2(T2),cacheClientB
使用当前过期的版本号尝试更新 RadioInventory
缓存对象。为防止 cacheClientA
的更改被覆盖,cacheClientB
Put 方法调用失败。缓存客户端通过使用 CacheItemVersionMismatch 的 ErrorCode 属性集来引发 DataCacheException 对象。这将显示在以下图表和代码示例中。
'later, at time T2, cacheClientB tries to
'update the FM radio inventory, throws DataCacheException with
'an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
Dim newRadioInventoryB As Integer = 130
cacheClientB.Put("RadioInventory", newRadioInventoryB, _
radioInventoryB.Version, "electronics")
//later, at time T2, cacheClientB tries to
//update the FM radio inventory, throws DataCacheException with
//an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
int newRadioInventoryB = 130;
cacheClientB.Put("RadioInventory", newRadioInventoryB,
radioInventoryB.Version,"electronics");
悲观并发模型
在悲观并发模型中,客户端显式锁定要执行操作的对象。其他请求锁定的操作(系统不阻止请求)被拒绝,直到释放锁定。当锁定对象时,锁定句柄返回为输出参数。解除对象锁定需要使用锁定句柄。 如果客户端应用程序在释放锁定对象前结束,则提供超时以释放锁定。锁定的对象永不过期,但如果超过过期时间,则锁定的对象可能在被解除锁定后立即过期。有关用于悲观并发模型的方法的详细信息,请参阅并发方法。
备注
不支持跨事务操作。使用缓存的应用程序负责确定锁定的顺序和检测死锁(如果有)。
警告
缓存中的锁定对象可以通过 Put 方法替换为任一缓存客户端。已启用缓存的应用程序负责为使用悲观并发模型的项目一致使用 PutAndUnlock。
另请参阅
概念
并发方法
AppFabric 缓存物理体系结构图(AppFabric 1.1 缓存)
AppFabric 缓存逻辑体系结构图(AppFabric 1.1 缓存)
开发缓存客户端
2012-03-05