Modelo de simultaneidade no Cache na Função do Azure

Importante

A Microsoft recomenda que todos os novos desenvolvimentos usem o Cache Redis do Azure. Para obter documentação e diretrizes atuais sobre como escolher uma oferta do Cache do Azure, confira qual oferta do Cache do Azure é certa para mim?

A arquitetura de cache permite que qualquer cliente de cache acesse qualquer dado em cache se seu acesso à rede e seus parâmetros de configuração forem adequados. Isso gera um desafio de simultaneidade.

Para ajudar o aplicativo a lidar com problemas de simultaneidade, há suporte a modelos de simultaneidade otimistas e pessimistas.

Modelo de simultaneidade otimista

No modelo de simultaneidade otimista, as atualizações de objetos em cache não aceitam bloqueios. Em vez disso, quando o cliente de cache recebe um objeto do cache, também obtém e armazena a versão atual do objeto. Quando uma atualização é necessária, o cliente de cache envia o novo valor do objeto juntamente com o objeto da versão armazenada. O sistema só atualiza o objeto se a versão enviada corresponde à versão atual do objeto no cache. Cada atualização de um objeto altera seu número de versão, o que impede que a atualização substitua as alterações feitas por outra pessoa.

O exemplo neste tópico ilustra como a simultaneidade otimista mantém a consistência dos dados.

Exemplo

Neste exemplo, dois clientes de cache (cacheClientA e cacheClientB) tentam atualizar o mesmo objeto em cache, tendo a mesma chave RadioInventory.

Hora Zero: ambos os clientes recuperam o mesmo objeto

No tempo zero (T0), ambos os clientes de cache instanciam uma classe DataCacheItem para capturar o objeto em cache que pretendem atualizar, juntamente com informações adicionais associadas a esse objeto em cache, como as informações de versão e marca. Isso é ilustrado no exemplo de código a seguir.

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

Observação

Embora este exemplo obtenha as informações de versão usando o método GetCacheItem para recuperar o objeto DataCacheItem , também é possível usar o método Get para obter o objeto DataCacheItemVersion associado ao item de cache recuperado.

Time One: A primeira atualização é bem-sucedida

No tempo um (T1), o cacheClientA atualiza o objeto em cache RadioInventory com um novo valor. Quando cacheClientA executa o método Put, a versão associada ao item de cache RadioInventory é incrementada. Nesse momento, cacheClientB tem um item de cache desatualizado. Isso é ilustrado no exemplo a seguir.

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

Tempo Dois: a segunda atualização falha

No tempo dois (T2), cacheClientB tenta atualizar o objeto em cache RadioInventory usando o que agora é um número de versão desatualizado. Para impedir que as alterações de cacheClientA sejam substituídas, a chamada por cacheClientB do método Put falha. O cliente de cache lança um objeto DataCacheException com a propriedade ErrorCode definida como CacheItemVersionMismatch. Isso é ilustrado no exemplo de código a seguir.

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

Modelo de simultaneidade pessimista

No modelo de simultaneidade pessimista, o cliente bloqueia objetos explicitamente para executar operações. Outras operações que solicitem bloqueios são rejeitadas (o sistema não bloqueia solicitações) até que os bloqueios sejam liberados. Quando um objeto é bloqueado, um identificador de bloqueio é retornado como um parâmetro de saída. O identificador de bloqueio é necessário para desbloquear o objeto. Caso o aplicativo cliente seja encerrado antes de liberar um objeto bloqueado, são fornecidos tempos limite para liberar os bloqueios. Objetos bloqueados nunca expiram, mas podem expirar imediatamente após o desbloqueio se tiverem excedido o tempo de expiração.

Para obter mais informações sobre os métodos usados com o modelo de simultaneidade pessimista, consulte Métodos simultâneos

Observação

Não há suporte a transações que abranjam mais de uma operação.

Observação

O aplicativo que usa o cache é responsável por determinar a ordem dos bloqueios e detectar eventuais deadlocks.

Aviso

Os objetos bloqueados no cache continuam passíveis de substituição por qualquer cliente de cache com o método Put. Os aplicativos habilitados para armazenamento em cache são responsáveis pelo uso consistente de PutAndUnlock para itens que usem o modelo de simultaneidade pessimista.

Consulte Também

Conceitos

Recursos de cache na função no cache do Azure