Condividi tramite


Modello di concorrenza in Cache nel ruolo di Azure

Importante

Microsoft consiglia tutti i nuovi sviluppi che usano Cache Redis di Azure. Per la documentazione e le indicazioni correnti sulla scelta di un'offerta di Cache di Azure, vedere Quale offerta di Cache di Azure è adatta per l'utente?

L'architettura di memorizzazione nella cache consente a tutti i client della cache con impostazioni di accesso di rete e configurazione appropriate di accedere ai dati memorizzati nella cache. Questo rappresenta un problema per la concorrenza.

Per consentire all'applicazione di gestire i problemi relativi alla concorrenza, sono supportati modelli di concorrenza ottimistica e pessimistica.

Modello di concorrenza ottimistica

Nel modello di concorrenza ottimistica gli aggiornamenti degli oggetti memorizzati nella cache non accettano blocchi. Al contrario, se il client della cache ottiene un oggetto dalla cache, ottiene e archivia la versione corrente di questo oggetto. Quando è necessario un aggiornamento, il client della cache invia il nuovo valore per l'oggetto insieme alla versione dell'oggetto archiviata. Nel sistema l'oggetto viene aggiornato solo se la versione inviata corrisponde alla versione corrente dell'oggetto nella cache. Ogni volta che un oggetto viene aggiornato, cambia il numero di versione. In questo modo si evita che l'aggiornamento sovrascriva le modifiche apportate da altri utenti.

L'esempio in questo argomento illustra in che modo il modello di concorrenza ottimistica garantisce la coerenza dei dati.

Esempio

In questo esempio, due client della cache (cacheClientA e cacheClientB) tentano di aggiornare lo stesso oggetto memorizzato nella cache, con la stessa chiave RadioInventory.

Ora zero: entrambi i client recuperano lo stesso oggetto

Al Tempo zero (T0), entrambi i client della cache creano un'istanza di una classe DataCacheItem per acquisire l'oggetto memorizzato nella cache da aggiornare e altre informazioni associate a questo oggetto, ad esempio informazioni sulla versione e sui tag. come illustra l'esempio di codice riportato di seguito.

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

Nota

Sebbene questo esempio ottenga le informazioni sulla versione usando il metodo GetCacheItem per recuperare l'oggetto DataCacheItem, è anche possibile usare il metodo Get per ottenere l'oggetto DataCacheItemVersion associato all'elemento cache recuperato.

Volta 1: il primo aggiornamento ha esito positivo

Al Tempo uno (T1), cacheClientA aggiorna l'oggetto memorizzato nella cache RadioInventory con un nuovo valore. Quando cacheClientA esegue il metodo Put, la versione associata all'elemento della cache RadioInventory viene incrementata. A questo punto, l'elemento della cache di cacheClientB non è aggiornato. Questo è illustrato nell'esempio seguente.

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

Ora due: il secondo aggiornamento ha esito negativo

Al Tempo due (T2), cacheClientB tenta di aggiornare l'oggetto memorizzato nella cache RadioInventory usando un numero di versione che risulta non aggiornato. Per evitare che vengano sovrascritte le modifiche di cacheClientA, la chiamata al metodo Put di cacheClientB ha esito negativo. Il client della cache genera un oggetto DataCacheException con la proprietà ErrorCode impostata su CacheItemVersionMismatch. come illustra l'esempio di codice riportato di seguito.

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

Modello di concorrenza pessimistica

Nel modello di concorrenza pessimistica il client blocca esplicitamente gli oggetti per eseguire operazioni. Altre operazioni che richiedono blocchi vengono rifiutate (nel sistema non vengono bloccate le richieste) finché i blocchi non vengono rilasciati. Quando gli oggetti sono bloccati, viene restituito un handle di blocco come parametro di output. L'handle di blocco è necessario per sbloccare l'oggetto. Se l'applicazione client termina prima che un oggetto bloccato venga liberato, sono disponibili timeout per il rilascio dei blocchi. Gli oggetti bloccati non scadono mai, ma possono scadere immediatamente dopo lo sblocco se è stata superata la scadenza prevista.

Per altre informazioni sui metodi usati con il modello di concorrenza pessimistico, vedere Metodi di concorrenza

Nota

Le transazioni che si estendono su più operazioni non sono supportate.

Nota

L'applicazione che usa la cache è responsabile della determinazione dell'ordine dei blocchi e del rilevamento di eventuali deadlock.

Avviso

Gli oggetti bloccati nella cache possono comunque essere sostituiti da qualsiasi client della cache con il metodo Put. Le applicazioni abilitate alla cache sono responsabili dell'uso coerente di PutAndUnlock per gli elementi basati sul modello di concorrenza pessimistica.

Vedere anche

Concetti

Funzionalità di Cache nel ruolo in Cache di Azure