并发模型(AppFabric 1.1 缓存)

Microsoft AppFabric 1.1 for Windows Server 体系结构允许任何缓存客户端公开访问任何缓存的数据(如果这些客户端具有适当的网络访问权限和配置设置)。这对于安全性和并发性是一大挑战。

为了降低安全风险,所有缓存客户端、缓存服务器和主要数据源服务器应是同一域的成员,且应部署在防火墙外围内。还强烈建议您确保缓存客户端上应用程序配置文件的安全。

为了帮助您的应用程序处理并发问题,AppFabric 支持乐观并发和悲观并发模型。要了解与这两个模型保持一致的方法,请参阅并发方法

乐观并发模型

在乐观并发模型中,缓存对象的更新不进行锁定。但当缓存客户端从缓存获得对象时,它还获得并存储该对象的当前版本。当需要进行更新时,缓存客户端会将对象新值与已存储的版本对象一起发送。仅当发送的版本与缓存中对象的当前版本匹配时,系统才会更新对象。对象的每次更新都会更改其版本号,这可以防止更新覆盖其他人的更改。

本主题中的示例介绍乐观并发模式如何维护数据的一致性。

示例

在本示例中,两个单独应用程序服务器上的两个缓存客户端(cacheClientAcacheClientB)尝试更新同一个名为 RadioInventory 的缓存对象。

时间零点:两个客户端都检索同一个对象

在时间零点 (T0),两个客户端都实例化 DataCacheItem 类,以捕获其要更新的缓存对象,以及与已该缓存对象关联的其他信息(例如,版本和标记信息)。这将显示在以下图表和代码示例中。

T0 的“Velocity”并发模型

'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 具有过期缓存项目。这将显示在以下图表和代码示例中。

T1 的“Velocity”并发模型

'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 方法调用失败。缓存客户端通过使用 CacheItemVersionMismatchErrorCode 属性集来引发 DataCacheException 对象。这将显示在以下图表和代码示例中。

T2 的“Velocity”并发模型

'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