Bloqueos exclusivos de artículos (bloqueo pesimista)
NCache proporciona un mecanismo de bloqueo pesimista que bloquea exclusivamente los datos almacenados en caché. Este mecanismo bloquea el elemento mediante el identificador de bloqueo, por lo que todos los demás usuarios no pueden realizar ninguna operación de escritura en ese elemento de caché. A LockHandle
está asociado con cada elemento bloqueado en el caché, que es devuelto por la API de bloqueo.
Note
Esta característica también está disponible en NCache Professional.
Un elemento bloqueado se puede recuperar/actualizar o desbloquear solo cuando su identificador de bloqueo se proporciona en el nivel API. Sin embargo, debes hacer esto con cuidado para evitar problemas de integridad de los datos. El bloqueo pesimista es un muy buen enfoque si el objetivo que se desea lograr es la coherencia de los datos.
Una vez que se adquiere un bloqueo usando LockHandle
, hay dos mecanismos para liberarlo. Ambos mecanismos se explican a continuación.
Liberación de bloqueos basada en el tiempo: También puede especificar el tiempo de espera de bloqueo mientras bloquea un elemento almacenado en caché. El tiempo de espera del bloqueo es el intervalo de tiempo después del cual el bloqueo se liberará automáticamente si no se realiza una llamada explícita para liberar el bloqueo durante el intervalo de tiempo de espera. Esto evitará que tus datos queden bloqueados por un tiempo infinito.
Apertura forzosa de cerraduras: Pueden surgir situaciones en entornos distribuidos cuando una aplicación que adquirió el bloqueo en un elemento de caché finaliza abruptamente o una aplicación finaliza su procesamiento de datos bloqueados. En tal situación, le gustaría liberar todos los bloqueos adquiridos por dicha aplicación. NCache proporciona una API de desbloqueo, que libera con fuerza el bloqueo del elemento de caché.
Note
Se recomienda utilizar el mecanismo de bloqueo basado en tiempo para que el elemento se desbloquee después de que se cumpla la condición para que los recursos permanezcan adquiridos durante el tiempo mínimo.
Cuándo usar el bloqueo pesimista
Tomemos el ejemplo discutido en el capítulo anterior. Si dos usuarios diferentes acceden a la misma cuenta bancaria en la misma instancia para una operación de actualización, podría producirse un conflicto que provocará incoherencia en los datos.
El bloqueo pesimista en este escenario permitirá que un usuario acceda a la cuenta a la vez. Al operar exitosamente, el usuario desbloquea el artículo y el control queda libre, lo que significa que el segundo usuario ahora puede acceder a la cuenta y hacer las modificaciones correspondientes.
Con este enfoque, los datos siguen siendo consistentes y no se produce ningún conflicto.
A LockHandle
está asociado con un elemento para garantizar que el elemento en particular permanezca inaccesible en todo el caché.
NCache proporciona un método que solicita exclusivamente el bloqueo, así como numerosas sobrecargas que manipulan el mecanismo de bloqueo.
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: Dolor, contiene, Contar, recuadro, Bloquear, Manija de bloqueo, Eliminar, Espacio de tiempo, descubrir.
Bloquear un elemento explícitamente
Puede bloquear explícitamente un elemento antes de realizar cualquier operación. Este método requiere un TimeSpan
para bloquear un elemento durante un tiempo específico. Sin embargo, si no desea que el bloqueo adquirido caduque, especifique TimeSpan.Zero
. Especificando no TimeSpan
bloqueará el elemento por un tiempo infinito.
El Lock
método utilizado en este ejemplo asocia un LockHandle
con una llave. Asegúrese de que el único LockHandle
está asociado a una única clave. Suelte el bloqueo antes de reutilizar la manija; de lo contrario, podría dar lugar a una inconsistencia en el comportamiento.
Si un elemento ya está bloqueado, se devolverá el valor falso, pero obtendrá el valor actualizado. LockHandle
.
advertencia
Bloquear un artículo por el mínimo TimeSpan
para evitar un estancamiento o un estado de hambruna.
El siguiente ejemplo crea un LockHandle
y luego bloquea un elemento con la llave Product:1001
durante un lapso de tiempo de 10 segundos, lo que significa que el artículo se desbloqueará automáticamente después de 10 segundos.
// Preconditions: Cache is already connected
// Item is already added in the cache
// Specify the key of the item
string key = $"Product:1001";
//Create a new LockHandle
LockHandle lockHandle = null;
// Specify time span of 10 seconds for which the item remains locked
TimeSpan lockSpan = TimeSpan.FromSeconds(10);
// Lock the item for a time span of 10 seconds
bool lockAcquired = cache.Lock(key, lockSpan, out lockHandle);
// Verify if the item is locked successfully
if (lockAcquired == true)
{
// Item has been successfully locked
}
else
{
// Key does not exist
// Item is already locked with a different LockHandle
}
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.
Bloquear un elemento durante la operación Obtener
Un elemento se puede bloquear durante su recuperación del caché. Esto significa que el elemento será inaccesible para otras personas a menos que lo liberes. En caso de que las claves no coincidan, se devuelve un valor nulo.
Si un elemento no está bloqueado y el
acquirelock
se establece en verdadero, obtendrá el elemento junto con LockHandle.Si un elemento está bloqueado y
acquirelock
se establece en falso y si pasa un LockHandle vacío incorrecto o nuevo, entonces unnull
se devuelve el valor, pero obtendrá el LockHandle que se usó para bloquear el elemento anteriormente.Si un elemento está bloqueado y
acquirelock
se establece en false y se pasa LockHandle correcto que se usó previamente para bloquear el elemento, luego obtendrá el valor.
advertencia
Bloquee un elemento durante el TimeSpan mínimo para evitar un punto muerto o la falta de subprocesos.
En este ejemplo, una clave y LockHandle
se especifica para recuperar el objeto almacenado en caché y bloquearlo. Debe especificar verdadero si necesita adquirir el candado. Aquí el artículo se bloquea con una expiración de 10 segundos, lo que significa que el artículo se desbloqueará automáticamente después de 10 segundos.
// Specify the key of the item
string key = $"Product:1001";
// Set acquireLock flag as true
bool acquireLock = true;
// Specify time span of 10 seconds for which the item remains locked
TimeSpan lockSpan = TimeSpan.FromSeconds(10);
//Create a new LockHandle
LockHandle lockHandle = null;
// Lock the item for a time span of 10 seconds
var result = cache.Get<Product>(key, acquireLock, lockSpan, ref lockHandle);
// Verify if the item is locked successfully
if (result != null)
{
// Item has been successfully locked
}
else
{
// Key does not exist
// Item is already locked with a different LockHandle
}
Liberar bloqueo con operación de actualización
Mientras actualiza un elemento, puede liberar el bloqueo permitiendo que otros utilicen los datos almacenados en caché. Para liberar con éxito el elemento bloqueado, deberá especificar el LockHandle
utilizado inicialmente para bloquear el elemento.
El
LockHandle
debe ser el mismo que el utilizado inicialmente para bloquear el elemento; de lo contrario, recibirá un mensaje de excepción que dice "El elemento está bloqueado".If
releaseLock
está configurado en falso, todavía tienes que pasar el correctoLockhandle
para actualizar el artículo.Si un elemento no está bloqueado, entonces el
LockHandle
yreleaseLock
no sirven de nada y se ignoran.
El siguiente ejemplo bloquea un elemento en el caché y luego obtiene el elemento usando el LockHandle
. Luego, el elemento se actualiza y luego se reinserta en el caché usando el recuadro API.
// Specify the key of the item
string key = $"Product:1001";
// Set acquireLock flag as true
bool acquireLock = true;
// Specify time span of 10 seconds for which the item remains locked
TimeSpan lockSpan = new TimeSpan(0, 0, 10);
// Initialize the lockHandle
LockHandle lockHandle = null;
CacheItem item = cache.GetCacheItem(key, acquireLock, lockSpan, ref lockHandle);
var product = new Product();
product = item.GetValue<Product>();
// Update the unitsinstock for the product
product.UnitsInStock = 200;
bool releaseLock = true;
// Item is already locked with a LockHandle
// Update the item and release the lock as well since releaseLock is set true
// Make sure that the LockHandle matches with the already added LockHandle
cache.Insert(key, item, null, lockHandle, releaseLock);
Liberar bloqueo explícitamente
Para liberar el bloqueo explícitamente en un elemento almacenado en caché previamente bloqueado; deberá especificar el LockHandle
utilizado inicialmente para bloquear el elemento.
Si LockHandle
no se guarda, también puede usar otra sobrecarga de Unlock
que solo toma la llave para desbloquear el artículo.
Note
Si un inválido LockHandle
se pasa, no se lanzará ninguna excepción pero el elemento permanecerá bloqueado.
El siguiente ejemplo obtiene un elemento ya bloqueado usando el LockHandle
y luego lo desbloquea usando el Unlock
API usando la Lockhandle
guardado antes.
// Specify the key of the item
string key = $"Product:1001";
// Set acquireLock flag as true
bool acquireLock = true;
// Specify time span of 10 seconds for which the item remains locked
TimeSpan lockSpan = TimeSpan.FromSeconds(10);
//Create a new LockHandle
LockHandle lockHandle = null;
Product result = cache.Get<Product>(key, acquireLock, lockSpan, ref lockHandle);
// Make sure that the item is already locked and the saved LockHandle is used
// Unlock locked item using saved LockHandle
cache.Unlock(key, lockHandle);
advertencia
NCache ignorará los bloqueos si otras sobrecargas de Get
, Insert
y Remove
se llaman métodos que no toman o usan LockHandle
.
Eliminar elemento con LockHandle
El método remove es un método básico que elimina la clave del caché y devuelve el objeto eliminado al cliente. Si se agrega un objeto personalizado al caché, el método de eliminación devolverá Objeto.
LockHandle
debe ser el mismo que se usó inicialmente para bloquear el elemento; de lo contrario, recibirá el mensaje de excepción que dice "El elemento está bloqueado".Si un elemento no está bloqueado, entonces
LockHandle
no sirve de nada y no se comprueba su validez.
El siguiente ejemplo obtiene un elemento que estaba previamente bloqueado usando el LockHandle
y luego lo elimina por el guardado LockHandle
del caché usando el Eliminar API.
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.
// Specify the key of the item
string key = $"Product:1001";
// Initialize the lockHandle
LockHandle lockHandle = null;
// Set acquireLock flag as true
bool acquireLock = true;
// Specify time span of 10 seconds for which the item remains locked
TimeSpan lockSpan = TimeSpan.FromSeconds(10);
// Get the item using the lockHandle
Product result = cache.Get<Product>(key, acquireLock, lockSpan, ref lockHandle);
// Removing locked item using saved lockHandle.
cache.Remove(key, lockHandle);
// Check if item is successfully removed
if (result != null)
{
if (result is Product)
{
Product product = (Product)result;
}
}
Consideración especial al usar el bloqueo de API
NCache proporciona un conjunto de API con y sin LockHandle
para recuperar/actualizar el elemento de caché. API sin LockHandle
ignorar el elemento Bloqueo. Por lo tanto, debería utilizar todas las API de bloqueo para la manipulación de datos. Por ejemplo, si un elemento está bloqueado y realiza una llamada API de actualización que no toma la LockHandle
como parámetro de entrada, el elemento se actualizará en la memoria caché independientemente de su estado de bloqueo.
Importante:
Cuando utilice una función de bloqueo, solo debe utilizar llamadas API que tomen LockHandle
como parámetros. Se puede utilizar una API que no admita identificadores de bloqueo, pero debe hacerse con mucho cuidado para que no afecte la integridad de los datos.
Note
En caso de Desalojo/Caducidad, NCache ignora los bloqueos, lo que significa que un elemento bloqueado se puede eliminar como resultado de una caducidad o un desalojo.
Comportamiento inteligente de topología
- Topología reflejada y replicada
En Mirror Topología, para todas las operaciones de bloqueo se adquiere un bloqueo en el nodo activo, y lo mismo LockHandle
Luego se replica en el nodo Pasivo para que cuando Pasivo se convierta en Activo, el elemento permanezca bloqueado. De manera similar, la llamada de desbloqueo también se replica en el nodo pasivo para desbloquear el elemento desde el nodo pasivo.
En Replicado Topología, el cliente está conectado a un nodo y para todas las operaciones de bloqueo el LockHandle
se genera el cual recibe la operación de bloqueo del cliente, y luego lo mismo LockHandle
se replicará en todos los demás nodos para mantener la coherencia de los datos. De manera similar, la operación de desbloqueo también se replicará en todos los demás nodos.
- Topología particionada y de réplica de partición
En Particionado topología, LockHandle
se genera y existe en el mismo nodo que contiene el elemento, y durante la transferencia de estado LockHandle
la información también se transfiere junto con el elemento en caso de que el elemento se mueva a otro nodo.
In Réplica de partición topología, LockHandle
se genera en el nodo activo que contiene el elemento, y lo mismo LockHandle
luego se replica en su réplica para mantener la coherencia de los datos y durante la transferencia de estado. LockHandle
La informació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, todas las operaciones basadas en bloqueos se realizan directamente en la caché agrupada, lo que significa que LockHandle
se genera y almacena en la caché agrupada. No se mantiene ninguna información relacionada con el bloqueo en la caché del cliente.
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.