Bloqueo con control de versiones de elementos de caché (bloqueo optimista)
Aunque la Bloqueo pesimista es un enfoque muy útil, existe una limitación en su uso, un elemento no se puede utilizar a menos que se realice al menos una operación en él por completo. Esto significa que el elemento permanece bloqueado hasta que se realiza completamente una tarea en el elemento. Esto puede provocar la muerte del hilo si un elemento permanece bloqueado durante mucho tiempo.
Note
Esta característica también está disponible en NCache Professional.
Aquí es donde el bloqueo optimista resulta útil ya que NCache utiliza el control de versiones de elementos de caché. CacheItemVersion
es una propiedad asociada con cada elemento de caché. Es un valor numérico que representa la versión del elemento almacenado en caché, que se incrementa en uno con cada actualización de un elemento. Esta propiedad le permite realizar un seguimiento de si se produce algún cambio en un elemento o no. Cuando recupera un elemento del caché, también recupera su versión actual en el caché.
Para aplicaciones de lectura intensiva, se prefiere el bloqueo optimista al bloqueo pesimista.
Cuándo usar el bloqueo optimista
En el ejemplo anterior, teníamos una única cuenta bancaria utilizada por dos usuarios simultáneamente. Supongamos que uno de los usuarios adquirió el candado para realizar una transacción de depósito en la cuenta bancaria. El Usuario2 está esperando que el Usuario1 libere el bloqueo para poder realizar la transacción de retiro. Tenga en cuenta que el Usuario1 pasa a un estado inestable debido a problemas de conectividad de red sin liberar el bloqueo. El usuario2 sigue esperando a que libere el bloqueo sin saber que hay ningún problema de conectividad, por lo que pasa al estado de inanición hasta que el primer usuario libera el bloqueo.
Para evitar este tipo de problemas, el bloqueo optimista es una solución útil. Al utilizar este tipo de bloqueo, si el Usuario1 desea actualizar la cuenta, puede actualizarla sin bloquearla y la versión del elemento se actualizará en consecuencia. Ahora, cuando el Usuario2 quiera actualizar los datos, obtendrá la versión actualizada según la versión del elemento y esto garantizará que no se produzcan problemas de integridad de los datos. Si algún usuario opera con los datos con la versión anterior del elemento, la operación fallará considerando que tiene una versión desactualizada del elemento.
CacheItemVersion
añade una dimensión adicional al desarrollo de la aplicación utilizando NCache. Se puede lograr una concurrencia optimista en las aplicaciones mediante NCache Versionado de elementos.
Cuando se agrega cualquier elemento al caché, la versión del elemento de caché regresa al cliente de caché. Este valor indica el número de actualizaciones realizadas en datos particulares. Con cada actualización, el valor de la versión del artículo aumenta.
Requisitos previos
- Para obtener información sobre los requisitos previos estándar necesarios para trabajar con todos NCache características del lado del cliente, consulte la página proporcionada en Requisitos previos de la API del lado del cliente.
- Para obtener detalles de la API, consulte: Añada, Dolor, Artículo de caché, Versión de elemento de caché, contiene, Contar, Obtener si es más nuevo, recuadro, Eliminar.
Recuperar y actualizar el artículo con la versión del artículo
An Añada la operación devuelve el CacheItemVersion
. Si se agrega un elemento por primera vez, se devuelve un valor largo que contiene la marca de tiempo de su creación. Esta versión se incrementará en "1" al realizar operaciones con esta clave en el futuro.
Optimistic Locking se asegura de que el usuario siempre obtenga la copia más actualizada del elemento del caché. Si el usuario sigue realizando funciones en la versión obsoleta, NCache lanza una excepción, para que el usuario obtenga el elemento actualizado del caché.
En el siguiente ejemplo, varias aplicaciones utilizan una memoria caché. El caché contiene los datos de los productos. UN CacheItem
se agrega al caché. Ambas aplicaciones obtienen el elemento con la versión actual, digamos versión. La aplicación 1 modifica el nombre del producto y luego reinserta el elemento en la memoria caché, lo que actualiza la versión del elemento a la nueva versión. La aplicación 2 todavía tiene el elemento con la versión. Si la Aplicación2 actualiza las unidades del artículo en stock y reinserta el artículo en la memoria caché, la inserción fallará. La aplicación 2 tendrá que buscar la versión actualizada para realizar la operación, en esa CacheItem
.
Note
Puede agregar un elemento en el caché usando ambos Añada or recuadro métodos.
- El
Add
El método agrega un nuevo elemento al caché y guarda la versión del elemento por primera vez. - El
Insert
El método agrega un elemento en el caché, si aún no está presente, mientras que sobrescribe el valor de un tiempo existente y actualiza la versión del elemento.
Las siguientes secciones de código explican las operaciones realizadas por la aplicación.
// 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
}
Note
Para garantizar que la operación sea a prueba de fallas, se recomienda manejar cualquier posible excepción dentro de su aplicación, como se explica en Manejo de fallas.
Recuperar el elemento si existe una versión más reciente en la caché
El GetIfNewer
El método se puede utilizar para recuperar el elemento existente si hay una versión más nueva disponible en la memoria caché. Al especificar la versión actual como argumento de la llamada al método, el caché devuelve el resultado apropiado.
Si la versión especificada es menor que la que está en el caché, solo entonces el método devuelve un nuevo elemento. nulo Será devuelto.
El siguiente ejemplo agrega un elemento en el caché con la clave Product:1001
y la versión del artículo y luego la recupera si hay alguna versión más nueva disponible usando el GetIfNewer
método que obtiene un elemento utilizando la versión del elemento de caché.
// 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
}
Quitar artículo con versión de artículo
Un elemento se puede eliminar del caché usando una sobrecarga de Eliminar, en función de la versión del artículo. Sin embargo, si la versión del elemento es diferente de la que está en el caché, obtiene una excepción que lo especifica.
El siguiente ejemplo muestra cómo eliminar un elemento de la memoria caché especificando la versión del elemento mediante el Eliminar método.
Consejo
Puede monitorear/verificar la eliminación:
- Contador "Cache Count" en NCache Monitorear or Contadores PerfMon.
- Usar
cache.Contains
una vez transcurrido el intervalo de vencimiento. - Usar
cache.Count
antes y después de especificar el vencimiento.
// 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);
Comportamiento inteligente de topología
- Para el espejo y el caché replicado
En Mirror Topología: cuando se agrega o actualiza un elemento, su versión se genera en el nodo activo y luego la misma versión se replica en el nodo pasivo junto con el elemento, de modo que cuando un nodo activo se vuelve pasivo, la versión del elemento sigue siendo la misma.
En Replicado Topología: el cliente está conectado a un nodo y la versión del elemento se genera en un nodo que recibe la operación de actualización/agregación del cliente; luego, la misma versión del elemento junto con el elemento se replica en todos los demás nodos para mantener la coherencia de los datos.
- Para el caché particionado y de réplica de partición
En Particionado Topología, la versión del artículo se genera y existe en el mismo nodo que contiene el artículo, y durante la transferencia de estado la versión también se transfiere junto con el artículo en caso de que el artículo se mueva a otro nodo.
En Réplica de partición Topología, la versión se genera en el nodo activo, que contiene el elemento y la misma versión junto con el elemento luego se replica en su réplica para mantener la coherencia de los datos y durante la transferencia de estado la versión también se transfiere junto con el elemento en caso de que el elemento se mueva a otro nodo.
- Caché de cliente
En Caché de cliente, toda la información relacionada con la versión se mantiene en la caché agrupada y, cada vez que se llama a una API relacionada con la versión, el usuario obtiene su versión de la caché agrupada.
Recursos adicionales
NCache proporciona una aplicación de muestra para el bloqueo de elementos GitHub.
Vea también
.NETO: Alachisoft.NCache.Runtime.Caching espacio de nombres
Java: com.alachisoft.ncache.runtime.caching espacio de nombres
Nodo.js: cache clase.
Pitón: ncache.runtime.caching clase.