Modèle de concurrence dans Azure In-Role Cache

Important

Microsoft recommande tous les nouveaux développements d’utiliser le Cache Redis Azure. Pour obtenir de la documentation et des conseils actuels sur le choix d’une offre Azure Cache, consultez Quelle offre Azure Cache est adaptée à moi ?

L'architecture de mise en cache permet à tout client de cache d'accéder aux données mises en cache s'il dispose de l'accès réseau et des paramètres de configuration appropriés. Ceci représente un défi en matière de concurrence.

Pour aider votre application à gérer les problèmes de concurrence, les modèles d'accès concurrentiel optimiste et pessimiste sont pris en charge.

Modèle d'accès concurrentiel optimiste

Dans le modèle d'accès concurrentiel optimiste, les mises à jour des objets mis en cache ne prennent pas de verrous. Au lieu de cela, quand le client de cache obtient un objet du cache, il en obtient et stocke également la version actuelle. Si une mise à jour est requise, le client de cache envoie la nouvelle valeur pour l'objet en même temps que l'objet version stocké. Le système met l'objet à jour uniquement si la version envoyée correspond à la version actuelle de l'objet en cache. Chaque mise à jour d'un objet modifie son numéro de version, ce qui empêche la mise à jour d'écraser les modifications apportées par quelqu'un d'autre.

L'exemple présenté dans cette rubrique illustre la manière dont l'accès concurrentiel optimiste maintient la cohérence des données.

Exemple

Dans cet exemple, deux clients de cache (cacheClientA et cacheClientB) tentent de mettre à jour le même objet mis en cache, car ils ont la même clé RadioInventory.

Heure zéro : les deux clients récupèrent le même objet

Au temps zéro (T0), les deux clients de cache instancient une classe DataCacheItem pour capturer l'objet mis en cache qu'ils ont l'intention de mettre à jour, ainsi que des données supplémentaires associées à cet objet, telles que des informations de version et de balise. En voici une illustration dans l’exemple de code suivant.

'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");

Notes

Bien que cet exemple obtienne les informations de version à l’aide de la méthode GetCacheItem pour récupérer l’objet DataCacheItem , il est également possible d’utiliser la méthode Get pour obtenir l’objet DataCacheItemVersion associé à l’élément de cache récupéré.

Heure 1 : La première mise à jour réussit

Au temps un (T1), cacheClientA met à jour l'objet mis en cache RadioInventory avec une nouvelle valeur. Quand cacheClientA exécute la méthode Put, la version associée à l'élément de cache RadioInventory est incrémentée. À ce moment, cacheClientB a un élément de cache obsolète. L'exemple suivant illustre ce concept.

'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);

Heure 2 : la deuxième mise à jour échoue

Au temps deux (T2), cacheClientB essaie de mettre à jour l'objet mis en cache RadioInventory en utilisant ce qui est désormais un numéro de version obsolète. Pour empêcher l'écrasement des modifications de cacheClientA, l'appel de la méthode cacheClientBPut échoue. Le client de cache lève un objet DataCacheException avec la propriété ErrorCode définie sur CacheItemVersionMismatch. En voici une illustration dans l’exemple de code suivant.

'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);

Modèle d'accès concurrentiel pessimiste

Dans le modèle d'accès concurrentiel pessimiste, le client verrouille explicitement des objets pour exécuter des opérations. Les autres opérations demandant des verrous sont rejetées (le système ne bloque pas les demandes) jusqu'à ce que les verrous soient libérés. Quand des objets sont verrouillés, un handle de verrou est renvoyé sous la forme d'un paramètre de sortie. Le handle de verrou est obligatoire pour déverrouiller l'objet. Si l'application cliente s'arrête avant la libération d'un objet verrouillé, des délais d'expiration sont fournis pour libérer les verrous. Les objets verrouillés n'expirent jamais, mais ils peuvent expirer immédiatement après leur déverrouillage si le délai d'expiration est écoulé.

Pour plus d’informations sur les méthodes utilisées avec le modèle d’accès concurrentiel pessimiste, consultez Méthodes d’accès concurrentiel

Notes

Les opérations de fractionnement des transactions ne sont pas prises en charge.

Notes

L'application utilisant le cache est responsable de la détermination de l'ordre des verrous et de la détection des blocages éventuels.

Avertissement

Tout client de cache peut remplacer les objets verrouillés dans le cache avec la méthode Put. Les applications prenant en charge le cache sont responsables de l'utilisation cohérente de l'opération PutAndUnlock pour les éléments qui utilisent le modèle d'accès concurrentiel pessimiste.

Voir aussi

Concepts

Fonctionnalités de In-Role Cache dans Azure Cache