同時実行モデル (Windows Server AppFabric キャッシュ)

Windows Server AppFabric アーキテクチャでは、キャッシュ クライアントで適切なネットワーク アクセスおよび構成が設定されている場合、任意のクライアントでキャッシュされているすべてのデータにオープンにアクセスできます。これは、セキュリティと同時実行の両方で問題となります。

セキュリティ リスクを軽減するために、すべてのキャッシュ クライアント、キャッシュ サーバー、およびプライマリ データ ソース サーバーを同じドメインのメンバーにし、ファイアウォールの境界内に展開してください。キャッシュ クライアント上のアプリケーション構成ファイルをセキュリティで保護することも強くお勧めします。

アプリケーションで同時実行の問題を解決できるようにするために、AppFabric ではオプティミスティック同時実行モデルとペシミスティック同時実行モデルをサポートしています。これらのモデルに合わせて利用できるメソッドについては、「同時実行メソッド (Windows Server AppFabric キャッシュ)」を参照してください。

オプティミスティック同時実行モデル

オプティミスティック同時実行モデルでは、キャッシュされたオブジェクトに対する更新はロックされません。代わりに、キャッシュ クライアントがキャッシュからオブジェクトを取得する場合、そのオブジェクトの現在のバージョンも取得して格納します。更新が必要な場合は、キャッシュ クライアントはオブジェクトの新しい値を、格納されているバージョンのオブジェクトと共に送信します。システムでは、送信されたバージョンがキャッシュ内にあるオブジェクトの現在のバージョンと一致する場合にのみ、オブジェクトを更新します。オブジェクトを更新するたびにバージョン番号が変更されるので、更新によって他のユーザーの変更内容が上書きされることを防止できます。

このトピックの例では、オプティミスティック同時実行でデータの整合性がどのように維持されるかを示します。

この例では、2 つの独立したアプリケーション サーバーにある 2 つのキャッシュ クライアント (cacheClientA および cacheClientB) によって、RadioInventory という名前のキャッシュされた同一オブジェクトを更新してみます。

タイム 0: 両方のクライアントが同じオブジェクトを取得する

タイム 0 (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");

ヒント

この例では、DataCacheItem オブジェクトを取得する GetCacheItem メソッドを使用してバージョン情報を取得していますが、Get メソッドを使用して、取得するキャッシュ項目に関連付けられている DataCacheItemVersion オブジェクトを取得することもできます。

タイム 1: 最初の更新が成功する

タイム 1 (T1) で、cacheClientA が、キャッシュされたオブジェクト RadioInventory を新しい値に更新します。cacheClientAPut メソッドを実行すると、キャッシュ項目 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 番目の更新が失敗する

タイム 2 (T2) で、cacheClientB は、古くなってしまったバージョン番号を使用して、キャッシュされたオブジェクト RadioInventory を更新しようとします。cacheClientA による変更が上書きされないように、cacheClientBPut メソッド呼び出しは失敗します。キャッシュ クライアントは、ErrorCode プロパティを CacheItemVersionMismatch に設定して、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");

ペシミスティック同時実行モデル

ペシミスティック同時実行モデルでは、クライアントは明示的にオブジェクトをロックして操作を実行します。このロックが解除されるまで、ロックを要求する他の操作は拒否されます (システムは要求をブロックしません)。オブジェクトがロックされると、出力パラメーターとしてロック ハンドルが返されます。オブジェクトのロックを解除するにはロック ハンドルが必要です。クライアント アプリケーションがロックされたオブジェクトを解放せずに終了した場合に備えて、ロックを解放するためのタイムアウトが用意されています。ロックされたオブジェクトの有効期限が切れることはありませんが、ロックが解除されたときに、有効期限を過ぎている場合は、直ちに有効期限切れになる可能性があります。ペシミスティック同時実行モデルで使用されるメソッドの詳細については、「同時実行メソッド (Windows Server AppFabric キャッシュ)」を参照してください。

ヒント

複数の操作にまたがるトランザクションはサポートされません。キャッシュを使用するアプリケーションは、必要に応じて、ロックの順序の決定およびデッドロックの検出を行う必要があります。

警告

キャッシュ内のロックされているオブジェクトであっても、任意のキャッシュ クライアントから Put メソッドを使用して置き換えることができます。キャッシュが有効なアプリケーションでは、ペシミスティック同時実行モデルを使用する項目については、常に PutAndUnlock を使用する必要があります。

関連項目

概念

同時実行メソッド (Windows Server AppFabric キャッシュ)
Windows Server AppFabric キャッシュの物理アーキテクチャ図
Windows Server AppFabric キャッシュ論理アーキテクチャ図
キャッシュ クライアントを開発する (Windows Server AppFabric キャッシュ)

  2011-12-05