Verrouillage avec gestion des versions des éléments de cache (verrouillage optimiste)
Tandis que Verrouillage pessimiste est une approche très utile, son utilisation comporte une limitation, un élément ne peut pas être utilisé à moins qu'au moins une opération ne soit effectuée complètement dessus. Cela signifie que l'élément reste verrouillé jusqu'à ce qu'une tâche soit entièrement exécutée sur l'élément. Cela peut entraîner une famine des threads si un élément reste verrouillé pendant une longue période.
Notes
Cette fonctionnalité est également disponible dans NCache Professional.
C'est là que le verrouillage optimiste s'avère utile puisque NCache utilise la gestion des versions des éléments du cache. CacheItemVersion
est une propriété associée à chaque élément du cache. Il s'agit d'une valeur numérique qui représente la version de l'élément mis en cache, qui s'incrémente de un à chaque mise à jour d'un élément. Cette propriété vous permet de savoir si une modification se produit ou non dans un élément. Lorsque vous récupérez un élément du cache, vous récupérez également sa version actuelle dans le cache.
Pour les applications à lecture intensive, le verrouillage optimiste est préféré au verrouillage pessimiste.
Quand utiliser le verrouillage optimiste
Dans l’exemple précédent, nous avions un seul compte bancaire utilisé par deux utilisateurs simultanément. Supposons que l'un des utilisateurs ait acquis le verrou pour effectuer une transaction de dépôt sur le compte bancaire. L'utilisateur 2 attend que l'utilisateur 1 libère le verrou pour pouvoir effectuer la transaction de retrait. Considérez que l'utilisateur 1 passe dans un état instable en raison de problèmes de connectivité réseau sans libérer le verrou. L'utilisateur 2 continue d'attendre qu'il libère le verrou sans avoir connaissance de problèmes de connectivité, il passe donc à l'état de famine jusqu'à ce que le premier utilisateur libère le verrou.
Pour éviter ce genre de problème, Optimistic Locking est une solution utile. En utilisant ce type de verrouillage, si l'utilisateur 1 souhaite mettre à jour le compte, il peut mettre à jour le compte sans le verrouiller et la version de l'élément sera mise à jour en conséquence. Désormais, lorsque l'utilisateur 2 souhaite mettre à jour les données, il obtiendra la version mise à jour en fonction de la version de l'élément, ce qui garantira qu'aucun problème d'intégrité des données ne se produira. Si un utilisateur opère sur les données avec l'ancienne version de l'élément, l'opération échouera étant donné qu'il dispose d'une version d'élément obsolète.
CacheItemVersion
ajoute une dimension supplémentaire au développement de l'application en utilisant NCache. Une concurrence optimiste peut être obtenue dans les applications en NCache Gestion des versions des articles.
Lorsqu'un élément est ajouté au cache, la version de l'élément de cache est renvoyée au client de cache. Cette valeur indique le nombre de mises à jour effectuées sur des données particulières. À chaque mise à jour, la valeur de la version de l'élément augmente.
Pré-requis
- Pour en savoir plus sur les prérequis standard requis pour travailler avec tous NCache fonctionnalités côté client, veuillez vous référer à la page donnée sur Prérequis de l'API côté client.
- Pour plus de détails sur l'API, reportez-vous à : Ajouter, ICache, CacheItem, CacheItemVersionCacheItemVersion, Inclus, que vous avez, Obtenir si plus récent, insérer, Effacer.
Récupérer et mettre à jour l'élément avec la version de l'élément
An Ajouter l'opération renvoie le CacheItemVersion
. Si un élément est ajouté pour la première fois, une valeur longue contenant le TimeStamp de sa création est renvoyée. Cette version sera incrémentée de « 1 » lors des opérations ultérieures sur cette clé.
Le verrouillage optimiste garantit que l'utilisateur obtient toujours la copie la plus à jour de l'élément à partir du cache. Si l'utilisateur continue d'exécuter des fonctions sur la version obsolète, NCache lève une exception, afin que l'utilisateur obtienne l'élément mis à jour à partir du cache.
Dans l'exemple ci-dessous, un cache est utilisé par plusieurs applications. Le cache contient les données des produits. UN CacheItem
est ajouté au cache. Les deux applications récupèrent l'élément avec la version actuelle, disons la version. Application1 modifie le nom du produit puis réinsère l'élément dans le cache, ce qui met à jour la version de l'élément vers la nouvelle version. L'application 2 contient toujours l'élément avec la version. Si Application2 met à jour les unités de l'article en stock et réinsère l'article dans le cache, l'insertion échouera. Application2 devra récupérer la version mise à jour pour effectuer l'opération, à ce sujet CacheItem
.
Notes
Vous pouvez ajouter un élément dans le cache en utilisant à la fois Ajouter or insérer méthodes.
- Les
Add
La méthode ajoute un nouvel élément au cache et enregistre la version de l'élément pour la première fois. - Les
Insert
La méthode ajoute un élément dans le cache, s'il n'est pas déjà présent, alors qu'elle écrase la valeur d'une heure existante et met à jour la version de l'élément.
Les sections de code suivantes expliquent les opérations effectuées par l'application.
// Precondition: Cache is already connected
// An item is added in the cache with itemVersion
// Specify the key of the cacheItem
string key = "Product:1001";
// Initialize the cacheItemVersion
CacheItemVersion version = null;
// Get the cacheItem previously added in the cache with the version
CacheItem cacheItem = cache.GetCacheItem(key, ref version);
// If result is not null
if (cacheitem != null)
{
// CacheItem is retrieved successfully with the version
// If result is Product type
var prod = new Product();
prod = cacheItem.GetValue<Product>();
prod.UnitsInStock++;
// Create a new cacheItem with updated value
var updateItem = new CacheItem(prod);
//Set the itemversion. This version will be used to compare the
// item version of cached item
updateItem.Version = version;
cache.Insert(key, updateItem);
// If it matches, the insert will be successful, otherwise it will fail
}
else
{
// Item could not be retrieved due to outdated CacheItemVersion
}
Notes
Pour garantir la sécurité de l'opération, il est recommandé de gérer toutes les exceptions potentielles au sein de votre application, comme expliqué dans Gestion des échecs.
Récupérer l'élément si une version plus récente existe dans le cache
Les GetIfNewer
La méthode peut être utilisée pour récupérer l’élément existant si une version plus récente est disponible dans le cache. En spécifiant la version actuelle comme argument de l'appel de méthode, le cache renvoie le résultat approprié.
Si la version spécifiée est inférieure à celle du cache, alors seulement la méthode renvoie un nouvel élément, sinon nul sera retourné.
L'exemple suivant ajoute un élément dans le cache avec la clé Product:1001
et la version de l'élément, puis le récupère si une version plus récente est disponible à l'aide du GetIfNewer
méthode qui récupère un élément à l'aide de la version de l'élément de cache.
// Get updated product from database against given product ID
Product product = FetchProductByProductID(1001);
// Generate a unique key for this item
string key = $"Product:{product.ProductID}";
// Create a new CacheItem
var item = new CacheItem(product);
// Add CacheItem to cache with new itemversion
CacheItemVersion version = cache.Insert(key, item);
// Get object from cache
var result = cache.GetIfNewer<Product>(key, ref version);
// Check if updated item is available
if (result != null)
{
// An item with newer version is available
if (result is Product)
{
// Perform operations according to business logic
}
}
else
{
// No new itemVersion is available
}
Supprimer l'article avec la version de l'article
Un élément peut être supprimé du cache en utilisant une surcharge de Effacer, en fonction de la version de l'article. Cependant, si la version de l'élément est différente de celle du cache, vous obtenez une exception le spécifiant.
L'exemple suivant montre comment supprimer un élément du cache en spécifiant la version de l'élément à l'aide de la Effacer méthode.
Conseil
Vous pouvez surveiller/vérifier la suppression :
- Compteur "Cache Count" dans NCache Surveiller or Compteurs de performances.
- En utilisant
cache.Contains
une fois le délai d'expiration écoulé. - En utilisant
cache.Count
avant et après avoir spécifié l'expiration.
// Get updated product from database against given product ID
Product product = FetchProductByProductID(1001);
// Cache key remains the same for this product
string key = $"Product:{product.ProductID}";
// Create a new CacheItem
var item = new CacheItem(product);
// Insert CacheItem to cache with new itemversion
CacheItemVersion version = cache.Insert(key, item);
// Remove the item from the cache using the itemVersion
cache.Remove(key, null, version);
Comportement judicieux de la topologie
- Pour le miroir et le cache répliqué
Dans le Miroir Topologie, lorsqu'un élément est ajouté ou mis à jour, sa version est générée au niveau du nœud actif et la même version est ensuite répliquée sur le nœud passif avec l'élément de sorte que lorsqu'un nœud actif devient passif, la version de l'élément reste la même.
Dans le Répliqué Topologie : le client est connecté à un nœud et la version de l'élément est générée sur un nœud qui reçoit l'opération de mise à jour/ajout du client, puis la même version de l'élément avec l'élément est répliquée sur tous les autres nœuds pour assurer la cohérence des données.
- Pour le cache partitionné et le cache de réplique de partition
Dans le Partitionné Topologie, la version de l'élément est générée et existe sur le même nœud qui contient l'élément, et pendant le transfert d'état, la version est également transférée avec l'élément au cas où l'élément serait déplacé vers un autre nœud.
Dans le Réplique de partition Topologie, la version est générée sur le nœud actif, qui contient l'élément et la même version avec l'élément est ensuite répliquée sur sa réplique pour des raisons de cohérence des données et pendant le transfert d'état, la version est également transférée avec l'élément au cas où l'élément serait déplacé vers un autre. nœud.
- Cache Client
Dans le Cache Client, toutes les informations relatives à la version sont conservées dans le cache cluster et chaque fois qu'une API liée à la version est appelée, l'utilisateur obtient sa version à partir du cache cluster.
Ressources additionnelles
NCache fournit un exemple d'application pour le verrouillage d'élément activé GitHub.
Voir aussi
.RAPPORTER: Alachisoft.NCache.Runtime.Caching espace de noms.
Java: com.alachisoft.ncache.runtime.caching espace de noms.
Node.js : Cache classe.
python: ncache.runtime.caching classe.