Lucchetti esclusivi sugli oggetti (blocco pessimistico)
NCache fornisce un meccanismo di blocco pessimistico che blocca esclusivamente i dati memorizzati nella cache. Questo meccanismo blocca l'elemento utilizzando l'handle di blocco in modo che a tutti gli altri utenti venga impedito di eseguire qualsiasi operazione di scrittura su quell'elemento della cache. UN LockHandle
è associato a ogni elemento bloccato nella cache, restituito dall'API di blocco.
Note:
Questa funzionalità è disponibile anche in NCache Professional.
Un elemento bloccato può essere recuperato/aggiornato o sbloccato solo quando il relativo handle di blocco viene fornito a livello API. Tuttavia, dovresti farlo con attenzione per evitare problemi di integrità dei dati. Il Pessimistic Locking è un ottimo approccio se l’obiettivo da raggiungere è la coerenza dei dati.
Una volta acquisito un blocco utilizzando LockHandle
, ci sono due meccanismi per rilasciarlo. Entrambi questi meccanismi sono spiegati di seguito.
Sblocco delle serrature a tempo: È inoltre possibile specificare il timeout del blocco durante il blocco di un elemento memorizzato nella cache. Il timeout del blocco è l'intervallo di tempo dopo il quale il blocco verrà rilasciato automaticamente se non viene effettuata alcuna chiamata esplicita per rilasciare il blocco durante l'intervallo di timeout. Ciò impedirà che i tuoi dati vengano bloccati per un periodo di tempo infinito.
Rilascio forzato delle serrature: Negli ambienti distribuiti possono verificarsi situazioni in cui un'applicazione che ha acquisito il blocco su un elemento della cache termina improvvisamente o un'applicazione finalizza l'elaborazione sui dati bloccati. In una situazione del genere vorresti rilasciare tutti i blocchi acquisiti da tale applicazione. NCache fornisce un'API di sblocco, che rilascia forzatamente il blocco dell'elemento della cache.
Note:
Si consiglia di utilizzare il meccanismo di blocco basato sul tempo in modo che l'oggetto venga sbloccato una volta soddisfatta la condizione in modo che le risorse rimangano acquisite per il tempo minimo.
Quando utilizzare il blocco pessimistico
Prendiamo l'esempio discusso nel capitolo precedente. Se due utenti diversi accedono allo stesso conto bancario contemporaneamente per un'operazione di aggiornamento, potrebbe verificarsi un conflitto che porterà all'incoerenza dei dati.
Il blocco pessimistico in questo scenario consentirà a un utente di accedere all'account contemporaneamente. Dopo aver eseguito correttamente l'operazione, l'utente sblocca l'elemento e il controllo viene liberato, il che significa che il secondo utente può ora accedere all'account e apportare le modifiche di conseguenza.
Utilizzando questo approccio, i dati rimangono coerenti e non si verifica alcun conflitto.
A LockHandle
è associato a un elemento per garantire che l'elemento particolare rimanga inaccessibile nella cache.
NCache fornisce un metodo che richiede esclusivamente Locking, nonché numerosi sovraccarichi che manipolano il meccanismo di Locking.
Prerequisiti
- Per conoscere i prerequisiti standard richiesti per lavorare con all NCache Per le funzionalità lato client fare riferimento alla pagina specificata Prerequisiti dell'API lato client.
- Per i dettagli dell'API, fare riferimento a: ICache, contiene, Contare, inserire, bloccare, Maniglia di blocco, Rimuovere, Intervallo di tempo, Sbloccare.
Blocca un elemento in modo esplicito
È possibile bloccare esplicitamente un elemento prima di eseguire qualsiasi operazione. Questo metodo richiede a TimeSpan
per bloccare un elemento per un periodo di tempo specificato. Se però non si desidera che il blocco acquisito scada specificarlo TimeSpan.Zero
. Specificando il n TimeSpan
bloccherà l'oggetto per un tempo infinito.
I Lock
Il metodo utilizzato in questo esempio associa a LockHandle
con una chiave. Si prega di assicurarsi che il singolo LockHandle
è associato ad un'unica chiave. Rilasciare la serratura prima di riutilizzare la maniglia; in caso contrario, potrebbe portare a un comportamento incoerente.
Se un elemento è già bloccato, verrà restituito il valore false, ma otterrai il valore aggiornato LockHandle
.
avvertimento
Blocca un oggetto per il minimo TimeSpan
per evitare uno stato di stallo o di fame.
L'esempio seguente crea a LockHandle
e poi blocca un oggetto con la chiave Product:1001
per un intervallo di tempo di 10 secondi, il che significa che l'oggetto verrà sbloccato automaticamente dopo 10 secondi.
// 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:
Per garantire che l'operazione sia a prova di errore, si consiglia di gestire eventuali potenziali eccezioni all'interno dell'applicazione, come spiegato in Gestione dei guasti.
Blocca un oggetto durante l'operazione Ottieni
Un elemento può essere bloccato durante il suo recupero dalla cache. Ciò significa che l'elemento sarà inaccessibile ad altri a meno che tu non lo rilasci. In caso di mancata corrispondenza delle chiavi, viene restituito un valore nullo.
Se un elemento non è bloccato e il
acquirelock
è impostato su true allora otterrai l'elemento insieme a LockHandle.Se un elemento è bloccato e
acquirelock
è impostato su false e se passi un LockHandle vuoto errato o nuovo allora anull
viene restituito il valore, ma otterrai il LockHandle che è stato utilizzato per bloccare l'elemento in precedenza.Se un elemento è bloccato e
acquirelock
è impostato su false e viene passato LockHandle corretto che è stato precedentemente utilizzato per bloccare l'elemento, quindi otterrai il valore.
avvertimento
Blocca un elemento per il TimeSpan minimo per evitare deadlock o fame di thread.
In questo esempio, una chiave e LockHandle
è specificato per recuperare l'oggetto memorizzato nella cache e bloccarlo. È necessario specificare true se è necessario acquisire il blocco. Qui l'oggetto è bloccato con una scadenza di 10 secondi, il che significa che l'oggetto verrà sbloccato automaticamente dopo 10 secondi.
// 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
}
Rilascia il blocco con l'operazione di aggiornamento
Durante l'aggiornamento di un elemento, puoi rilasciare il blocco consentendo ad altri di utilizzare i dati memorizzati nella cache. Per rilasciare con successo l'oggetto bloccato, dovrai specificare il file LockHandle
inizialmente utilizzato per bloccare l'oggetto.
I
LockHandle
dovrebbe essere lo stesso utilizzato inizialmente per bloccare l'oggetto, altrimenti riceverai un messaggio di eccezione che dice "L'oggetto è bloccato".If
releaseLock
è impostato su false, devi comunque passare il correttoLockhandle
per aggiornare l'elemento.Se un elemento non è bloccato, il file
LockHandle
edreleaseLock
non servono e vengono ignorati.
L'esempio seguente blocca un elemento nella cache e quindi ottiene l'elemento utilizzando il file LockHandle
. L'elemento viene quindi aggiornato e quindi reinserito nella cache utilizzando il file inserire 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);
Rilascia il blocco in modo esplicito
Per rilasciare esplicitamente il blocco su un elemento memorizzato nella cache precedentemente bloccato; dovrai specificare il LockHandle
inizialmente utilizzato per bloccare l'oggetto.
Se l' LockHandle
non viene salvato, puoi anche usare un altro overload di Unlock
che prende solo la chiave per sbloccare l'oggetto.
Note:
Se invalido LockHandle
viene superato, non verrà generata alcuna eccezione ma l'elemento rimarrà bloccato.
L'esempio seguente ottiene un elemento già bloccato utilizzando LockHandle
e poi lo sblocca usando il Unlock
API utilizzando il Lockhandle
salvato prima.
// 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);
avvertimento
NCache ignorerà i blocchi se altri sovraccarichi di Get
, Insert
e Remove
vengono chiamati metodi che non prendono o non usano LockHandle
.
Rimuovere l'elemento con LockHandle
Il metodo di rimozione è un metodo di base che rimuove la chiave dalla cache e restituisce l'oggetto rimosso al client. Se un oggetto personalizzato viene aggiunto alla cache, il metodo di rimozione restituirà Object.
LockHandle
dovrebbe essere lo stesso utilizzato inizialmente per bloccare l'oggetto, altrimenti riceverai il messaggio di eccezione che dice "L'oggetto è bloccato".Se un elemento non è bloccato, allora
LockHandle
non è di alcuna utilità e la sua validità non viene verificata.
L'esempio seguente ottiene un elemento precedentemente bloccato utilizzando il metodo LockHandle
e quindi lo rimuove dal salvato LockHandle
dalla cache usando il Rimuovere API.
Consiglio
Puoi monitorare/verificare la rimozione:
- Contatore "Conteggio cache" in entrata NCache Monitorare or Contatori PerfMon.
- utilizzando
cache.Contains
una volta trascorso l'intervallo di scadenza. - utilizzando
cache.Count
prima e dopo aver specificato la scadenza.
// 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;
}
}
Considerazioni speciali durante l'utilizzo del blocco API
NCache fornisce un set di API con e senza LockHandle
per recuperare/aggiornare l'elemento della cache. API senza a LockHandle
ignora l'elemento Bloccato. Quindi dovresti utilizzare tutte le API di blocco per la manipolazione dei dati. Ad esempio, se un elemento è bloccato ed effettui una chiamata API di aggiornamento che non accetta il file LockHandle
come parametro di input, l'elemento verrà aggiornato nella cache indipendentemente dal suo stato di blocco.
Consigli
Quando utilizzi una funzionalità di blocco, dovresti utilizzare solo le chiamate API che accettano LockHandle
come parametri. È possibile utilizzare un'API che non accetta handle di blocco, ma deve essere eseguita con molta attenzione in modo che non influisca sull'integrità dei dati.
Note:
In caso di sfratto/scadenza, NCache ignora i blocchi, il che significa che un oggetto bloccato può essere rimosso a seguito di scadenza o sfratto.
Topologia Comportamento saggio
- Topologia speculare e replicata
Nel Specchio Topologia, per tutte le operazioni di blocco viene acquisito un blocco sul nodo attivo e lo stesso LockHandle
viene quindi replicato sul nodo Passivo in modo che quando Passivo diventa Attivo, l'elemento rimarrà bloccato. Allo stesso modo, la chiamata di sblocco viene replicata anche sul nodo Passivo per sbloccare l'elemento dal nodo Passivo.
Nel replicato Topologia, il client è connesso a un nodo e per tutte le operazioni di blocco il LockHandle
viene generato che riceve l'operazione di blocco del client e quindi la stessa cosa LockHandle
verrà replicato su tutti gli altri nodi per la coerenza dei dati. Allo stesso modo, l'operazione di sblocco verrà replicata anche su tutti gli altri nodi.
- Topologia partizionata e di replica delle partizioni
Nel Partitioned Topologia, LockHandle
viene generato ed esiste sullo stesso nodo che contiene l'elemento e durante il trasferimento di stato LockHandle
le informazioni vengono anche trasferite insieme all'elemento nel caso in cui l'elemento si sposti su un altro nodo.
In Partizione-Replica Topologia, LockHandle
viene generato sul nodo attivo che contiene l'elemento e lo stesso LockHandle
viene quindi replicato nella relativa replica per la coerenza dei dati e durante il trasferimento di stato. LockHandle
le informazioni vengono trasferite insieme all'elemento anche nel caso in cui l'elemento venga spostato su un altro nodo.
- Cache cliente
Nel Cache cliente, tutte le operazioni basate sui blocchi vengono eseguite direttamente nella cache in cluster, il che significa che LockHandle
viene generato e archiviato nella cache in cluster. Nella cache del client non vengono conservate informazioni relative al blocco.
Risorse addizionali
NCache fornisce un'applicazione di esempio per il blocco dell'elemento GitHub.
Vedere anche
.NETTO: Alachisoft.NCache.Memorizzazione.della.cache spazio dei nomi.
Giava: com.alachisoft.ncache.cache.di.runtime spazio dei nomi.
Node.js: Cache classe.
Pitone: ncache.cache.di.runtime classe.