Azure In-Role Cache のコンカレンシー モデル

重要

Microsoft では、すべての新しい開発で Azure Redis Cache を使用することをお勧めします。 Azure Cache オファリングの選択に関する最新のドキュメントとガイダンスについては、「自分に適した Azure Cache オファリング」を参照してください。

このキャッシュ アーキテクチャでは、クライアントに適切なネットワーク アクセスと構成設定があれば、あらゆるキャッシュ クライアントがキャッシュされているあらゆるデータにアクセスできます。 この場合、コンカレンシーが難しくなります。

アプリケーションでコンカレンシーの問題に対処するために、オプティミスティック コンカレンシー モデルとペシミスティック コンカレンシー モデルがサポートされます。

オプティミスティック コンカレンシー モデル

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

このトピックの例は、オプティミスティック コンカレンシーがデータの一貫性を維持するしくみを図示しています。

この例では、2 つのキャッシュ クライアント (cacheClientAcacheClientB) は、同じキー RadioInventory を持つ、キャッシュされている同じオブジェクトを更新しようとします。

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

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

'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 = _
        cacheClientB.GetCacheItem("RadioInventory")
//cacheClientA pulls the FM radio inventory from cache
DataCacheFactory clientACacheFactory = new DataCacheFactory();
DataCache cacheClientA = clientACacheFactory.GetCache("catalog");
DataCacheItem radioInventoryA = 
    cacheClientA.GetCacheItem("RadioInventory");

//cacheClientB pulls the same FM radio inventory from cache
DataCacheFactory clientBCacheFactory = new DataCacheFactory();
DataCache cacheClientB = clientBCacheFactory.GetCache("catalog");
DataCacheItem radioInventoryB= 
    cacheClientB.GetCacheItem("RadioInventory");

注意

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

時刻 1: 最初の更新が成功しました

タイム 1 (T1) では、cacheClientA は、キャッシュ済みオブジェクト RadioInventory を新しい値で更新します。 cacheClientAPut メソッドを実行すると、RadioInventory キャッシュ項目に関連付けられているバージョンがインクリメントします。 この時点で、cacheClientB のキャッシュ項目が古くなります。 この例を次に示します。

'at time T1, cacheClientA updates the FM radio inventory
Dim newRadioInventoryA As Integer = 155

cacheClientA.Put("RadioInventory", newRadioInventoryA, _
                 radioInventoryA.Version)
//at time T1, cacheClientA updates the FM radio inventory
int newRadioInventoryA = 155;

cacheClientA.Put("RadioInventory", newRadioInventoryA, 
    radioInventoryA.Version);

時刻 2: 2 番目の更新が失敗する

タイム 2 (T2) では、cacheClientB は、古くなってしまったバージョン番号を使用し、キャッシュされたオブジェクト RadioInventory を更新しようとします。 cacheClientA からの変更が上書きされないように、cacheClientBPut メソッドの呼び出しは失敗します。 キャッシュ クライアントは、ErrorCode プロパティが CacheItemVersionMismatch に設定された DataCacheException オブジェクトをスローします。 これを次のコード例に示します。

'later, at time T2, cacheClientB tries to 
'update the FM radio inventory, receives DataCacheException with
'an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
Dim newRadioInventoryB As Integer = 130

cacheClientB.Put("RadioInventory", newRadioInventoryB, _
                 radioInventoryB.Version)
//later, at time T2, cacheClientB tries to 
//update the FM radio inventory, receives DataCacheException with
//an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
int newRadioInventoryB = 130;

cacheClientB.Put("RadioInventory", newRadioInventoryB,
    radioInventoryB.Version);

ペシミスティックコンカレンシー モデル

ペシミスティック コンカレンシー モデルでは、クライアントは明示的にオブジェクトをロックし、操作を実行します。 ロックが解除されるまで、ロックを要求する他の操作は拒否されます (要求をブロックされません)。 オブジェクトがロックされると、出力パラメーターとしてロック ハンドルが返されます。 オブジェクトのロックを解除するにはロック ハンドルが必要です。 ロックされたオブジェクトを解放せずにクライアント アプリケーションが終了した場合に備え、ロックを解放するためのタイムアウトが用意されています。 ロックされたオブジェクトの有効期限が切れることはありませんが、ロックが解除されたときに有効期限を過ぎている場合、すぐに有効期限切れになる可能性があります。

ペシミスティック コンカレンシー モデルで使用されるメソッドの詳細については、「コンカレンシー メソッド」を参照してください。

注意

複数の操作にまたがるトランザクションはサポートされません。

注意

キャッシュを使用するアプリケーションは、必要に応じて、ロックの順序を決定し、デッドロックを検出する必要があります。

警告

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

参照

概念

Azure Cache の In-Role Cache の機能