Modelli di concorrenza (Memorizzazione nella cache di AppFabric 1.1)

L'architettura di Microsoft AppFabric 1.1 per Windows Server consente a tutti i client di accedere apertamente ai dati memorizzati nella cache se l'accesso di rete e le impostazioni di configurazione del client sono appropriati. Ciò rappresenta un problema per la sicurezza e la concorrenza.

Per ridurre i rischi per la sicurezza, è necessario che tutti i client di cache, i server di cache e il server di origine dei dati primari siano membri dello stesso dominio e che siano sviluppati all'interno del perimetro di un firewall. Si consiglia, inoltre, di proteggere i file di configurazione dell'applicazione sui client di cache.

Per consentire all'applicazione di gestire i problemi relativi alla concorrenza, AppFabric supporta modelli di concorrenza ottimistica e pessimistica. Per informazioni sui metodi disponibili per allinearsi a tali modelli, vedere Metodi di concorrenza.

Modello di concorrenza ottimistico

Nel modello di concorrenza ottimistico, gli aggiornamento degli oggetti memorizzati nella cache non hanno blocchi. Al contrario, se il client di cache ottiene un oggetto dalla cache, ottiene e memorizza la versione corrente di tale oggetto. Quando è necessario un aggiornamento, il client di cache invia il nuovo valore dell'oggetto insieme alla versione dell'oggetto memorizzata. Nel sistema l'oggetto viene aggiornato solo se la versione inviata corrisponde alla versione corrente dell'oggetto memorizzata nella cache. Tutti gli aggiornamenti di un oggetto comportano la modifica del numero di versione, che impedisce all'aggiornamento di sovrascrivere le modifiche apportate da altri utenti.

Nell'esempio in questo argomento viene illustrato in che modo il modello di concorrenza ottimistico consente di mantenere i dati consistenti.

Esempio

In questo esempio, due client di cache (cacheClientA e cacheClientB) in due server applicazioni diversi tentano di aggiornare lo stesso oggetto memorizzato nella cache, denominato RadioInventory.

Tempo zero: entrambi i client recuperano lo stesso oggetto

Al Tempo zero (T0), entrambi i client di cache creano un'istanza della classe DataCacheItem per acquisire l'oggetto memorizzato nella cache da aggiornare e ulteriori informazioni associate a tale oggetto,come ad esempio informazioni sulla versione e sui tag. Ciò è illustrato nel diagramma seguente e nell'esempio di codice.

Modello di concorrenza "Velocity" a T0

'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", "electronics")

'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 = _
        cacheClientA.GetCacheItem("RadioInventory", "electronics")
//cacheClientA pulls the FM radio inventory from cache
DataCacheFactory clientACacheFactory = new DataCacheFactory();
DataCache cacheClientA = clientACacheFactory.GetCache("catalog");
DataCacheItem radioInventoryA = 
    cacheClientA.GetCacheItem("RadioInventory","electronics");

//cacheClientB pulls the same FM radio inventory from cache
DataCacheFactory clientBCacheFactory = new DataCacheFactory();
DataCache cacheClientB = clientBCacheFactory.GetCache("catalog");
DataCacheItem radioInventoryB= 
    cacheClientA.GetCacheItem("RadioInventory", "electronics");

Nota

Benché nell'esempio le informazioni sulla versione sono ottenute utilizzando il metodo GetCacheItem per recuperare l'oggetto DataCacheItem, è possibile utilizzare anche il metodo Get per ottenere l'oggetto DataCacheItemVersion associato all'elemento di cache recuperato.

Tempo uno: il primo aggiornamento viene completato

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 nella cache di cacheClientB non è aggiornato. Ciò è illustrato nel diagramma seguente e nell'esempio di codice.

Modello di concorrenza "Velocity" a T1

'at time T1, cacheClientA updates the FM radio inventory
Dim newRadioInventoryA As Integer = 155

cacheClientA.Put("RadioInventory", newRadioInventoryA, _
                 radioInventoryA.Version, "electronics")
//at time T1, cacheClientA updates the FM radio inventory
int newRadioInventoryA = 155;

cacheClientA.Put("RadioInventory", newRadioInventoryA, 
    radioInventoryA.Version,"electronics");

Tempo due: il secondo aggiornamento ha esito negativo

Al Tempo due (T2), cacheClientB tenta di aggiornare l'oggetto memorizzato nella cache RadioInventory utilizzando un numero di versione che risulta non aggiornato. Per impedire la sovrascrittura delle modifiche da cacheClientA, la chiamata del metodo Put di cacheClientB ha esito negativo. Il client di cache genera un oggetto DataCacheException con la proprietà ErrorCode impostata su CacheItemVersionMismatch. Ciò è illustrato nel diagramma seguente e nell'esempio di codice.

Modello di concorrenza "Velocity" a T2

'later, at time T2, cacheClientB tries to 
'update the FM radio inventory, throws DataCacheException with
'an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
Dim newRadioInventoryB As Integer = 130

cacheClientB.Put("RadioInventory", newRadioInventoryB, _
                 radioInventoryB.Version, "electronics")
//later, at time T2, cacheClientB tries to 
//update the FM radio inventory, throws DataCacheException with
//an error code equal to DataCacheErrorCode.CacheItemVersionMismatch.
int newRadioInventoryB = 130;

cacheClientB.Put("RadioInventory", newRadioInventoryB,
    radioInventoryB.Version,"electronics");

Modello di concorrenza pessimistico

Nel modello di concorrenza pessimistico, 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 parametri 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 time-out per il rilascio dei blocchi. Gli oggetti bloccati non scadono mai ma possono scadere immediatamente dopo lo sblocco se la relativa scadenza è trascorsa. Per ulteriori informazioni sui metodi utilizzati nel modello di concorrenza pessimistico, vedere Metodi di concorrenza.

Nota

Le transazioni che si estendono tra più operazioni non sono supportate. L'applicazione che utilizza la cache è responsabile della determinazione dell'ordine dei blocchi e del rilevamento di eventuali blocchi critici.

Avviso

Gli oggetti bloccati nella cache possono comunque essere restituiti da qualsiasi client cache con il metodo Put. Le applicazioni abilitate alla cache sono responsabili per l'uso coerente di PutAndUnlock per gli elementi che utilizzano il modello di concorrenza pessimistico.

Vedere anche

Concetti

Metodi di concorrenza
Diagramma dell'architettura fisica della memorizzazione nella cache di AppFabric (Memorizzazione nella cache di AppFabric 1.1)
Diagramma dell'architettura logica della memorizzazione nella cache di AppFabric (Memorizzazione nella cache di AppFabric 1.1)
Sviluppo di un client della cache

  2012-03-05