Compartir a través de


Modelo de simultaneidad para el Servicio de caché administrado de Azure

Importante

Microsoft recomienda todos los nuevos desarrollos que usen Azure Redis Cache. Para obtener documentación actual e instrucciones sobre cómo elegir una oferta de Azure Cache, consulte ¿Qué oferta de Azure Cache es adecuada para mí?

La arquitectura de almacenamiento en caché permite que cualquier cliente de caché acceda a cualquier dato en caché si esos clientes tienen las opciones apropiadas de configuración y de acceso a la red. Esto presenta un reto para la simultaneidad.

Para ayudar a que su aplicación aborde los problemas de simultaneidad, existen modelos de simultaneidad optimista y pesimista.

Modelo de simultaneidad optimista

En el modelo de simultaneidad optimista, las actualizaciones de los objetos en caché no aceptan bloqueos. En su lugar, cuando el cliente de caché toma un objeto de la caché, también obtiene y almacena la versión actual de ese objeto. Cuando es necesaria una actualización, el cliente de caché envía el nuevo valor del objeto junto con el objeto de la versión guardada. El sistema solo actualiza el objeto si la versión enviada coincide con la versión actual del objeto en la caché. Cada actualización de un objeto cambia su número de versión, lo que evita que la actualización sobrescriba los cambios de alguien más.

El ejemplo en este tema ilustra la forma en que la simultaneidad optimista mantiene la coherencia de los datos.

Ejemplo

En este ejemplo, dos clientes de caché (cacheClientA y cacheClientB) intentan actualizar el mismo objeto en caché, con la misma clave RadioInventory.

Tiempo cero: ambos clientes recuperan el mismo objeto

En el momento cero (T0), ambos clientes de caché crean instancias de una clase DataCacheItem para capturar el objeto en caché que pretenden actualizar, junto con información adicional asociada con ese objeto en caché, como la información de la versión y de las etiquetas. Esto se muestra en el siguiente código de ejemplo.

'cacheClientA pulls the FM radio inventory from cache
Dim strACSKey = "[Authentication token]"
Dim clientAFactorySecurity = New DataCacheSecurity(strAcsKey)

Dim clientAFactoryConfiguration = New DataCacheFactoryConfiguration()
'Set up desired parameters for Cache Factory
clientAFactoryConfiguration.SecurityProperties = clientAFactorySecurity

Dim clientACacheFactory As DataCacheFactory = New DataCacheFactory(clientAFactoryConfiguration)
Dim cacheClientA As DataCache = _
        clientACacheFactory.GetCache("catalog")
Dim radioInventoryA As DataCacheItem = _
        cacheClientA.GetCacheItem("RadioInventory")

'cacheClientB pulls the same FM radio inventory from cache
'clientBFactorySecurity and clientBFactoryConfiguration omitted for space
Dim clientBCacheFactory As DataCacheFactory = New DataCacheFactory(clientBFactoryConfiguration)
Dim cacheClientB As DataCache = _
       clientBCacheFactory.GetCache("catalog")
Dim radioInventoryB As DataCacheItem = _
        cacheClientB.GetCacheItem("RadioInventory")
//cacheClientA pulls the FM radio inventory from cache
string strACSKey = "[Authentication token]";
DataCacheSecurity clientAFactorySecurity = new DataCacheSecurity(strAcsKey);

DataCacheFactoryConfiguration clientAFactoryConfiguration = new DataCacheFactoryConfiguration();
// Set up desired parameters for Cache Factory
clientAFactoryConfiguration.SecurityProperties = clientAFactorySecurityDataCacheFactory;

clientACacheFactory = new DataCacheFactory(clientAFactoryConfiguration);
DataCache cacheClientA = clientACacheFactory.GetCache("catalog");
DataCacheItem radioInventoryA = 
    cacheClientA.GetCacheItem("RadioInventory");

//cacheClientB pulls the same FM radio inventory from cache
// clientBFactorySecurity and clientBFactoryConfiguration omitted for space
DataCacheFactory clientBCacheFactory = new DataCacheFactory();
DataCache cacheClientB = clientBCacheFactory.GetCache("catalog");
DataCacheItem radioInventoryB= 
    cacheClientB.GetCacheItem("RadioInventory");

Nota

Aunque en este ejemplo se obtiene la información de versión mediante el método GetCacheItem para recuperar el objeto DataCacheItem , también es posible usar el método Get para obtener el objeto DataCacheItemVersion asociado al elemento de caché recuperado.

Hora uno: la primera actualización se realiza correctamente

En el momento uno (T1), cacheClientA actualiza el objeto en caché RadioInventory con un nuevo valor. Cuando cacheClientA ejecuta el método Put, la versión asociada al elemento de caché RadioInventory aumenta. En este momento, cacheClientB tiene un elemento de caché desactualizado. Esto se muestra en el ejemplo siguiente.

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

Hora dos: se produce un error en la segunda actualización

En el momento dos (T2), cacheClientB intenta actualizar el objeto en caché RadioInventory con un número de versión que ahora está desactualizado. Para evitar que se sobrescriban los cambios de cacheClientA, la llamada al método Put de cacheClientB genera un error. El cliente de caché produce un objeto DataCacheException con la propiedad ErrorCode establecida en CacheItemVersionMismatch. Esto se muestra en el siguiente código de ejemplo.

'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 simultaneidad pesimista

En el modelo de simultaneidad pesimista, el cliente bloquea expresamente los objetos para realizar las operaciones. Se rechazan otras operaciones que requieren bloqueos (el sistema no bloquea solicitudes) hasta que se levantan los bloqueos. Cuando los objetos están bloqueados, se devuelve un controlador de bloqueo como parámetro de salida. Se requiere el controlador de bloqueo para desbloquear el objeto. En caso de que la aplicación cliente finalice antes de liberar un objeto bloqueado, existen tiempos de espera para liberar los bloqueos. Los objetos bloqueados no expiran nunca, pero pueden expirar de inmediato una vez que se desbloquean si ya ha transcurrido su plazo de expiración.

Para obtener más información sobre los métodos usados con el modelo de simultaneidad pesimista, consulte Métodos de simultaneidad.

Nota

No se admiten las transacciones que se extiendan en varias operaciones.

Nota

La aplicación que use la memoria caché es responsable de determinar el orden de los bloqueos y detectar los interbloqueos, de existir.

Advertencia

Cualquier cliente de caché aún puede reemplazar los objetos bloqueados con el método Put. Las aplicaciones compatibles con caché son responsables de usar de forma coherente PutAndUnlock para los elementos que usan el modelo de simultaneidad pesimista.

Vea también

Otros recursos

Características del Servicio de caché administrado de Azure