Compartir a través de


Transacciones y control de simultaneidad optimista

SE APLICA A: NoSQL

Las transacciones entre bases de datos proporcionan un modelo de programación seguro y predecible para tratar los cambios simultáneos que se producen en los datos. Las bases de datos relacionales tradicionales, como SQL Server, permiten escribir la lógica de negocios mediante procedimientos almacenados y desencadenadores y, a continuación, enviarlos al servidor para su ejecución directamente en el motor de base de datos.

Con las bases de datos relacionales tradicionales, es necesario tratar con dos lenguajes de programación diferentes: un lenguaje de programación de aplicaciones no transaccionales, como JavaScript, Python, C#o Java; y un lenguaje de programación transaccional, como T-SQL, que la base de datos ejecuta de forma nativa.

El motor de base de datos de Azure Cosmos DB admite transacciones compatibles con ACID (atomicidad, coherencia, aislamiento, durabilidad) compatibles con el aislamiento de instantáneas. Todas las operaciones de base de datos dentro del ámbito de la partición lógica de un contenedor se ejecutan transaccionalmente dentro del motor de base de datos hospedado por la réplica de la partición. Estas operaciones incluyen operaciones de escritura (actualización de uno o varios elementos de la partición lógica) y operaciones de lectura.

En la tabla siguiente se enumeran diferentes operaciones y tipos de transacción:

operación Tipo de operación Transacción de un solo elemento o de varios elementos
Inserción (sin necesidad de un desencadenador previo o posterior) Escritura Transacción de un elemento único
Inserción (con un desencadenador previo o posterior) Escritura y lectura Transacción de varios elementos
Reemplazo (sin necesidad de un desencadenador previo o posterior) Escritura Transacción de un elemento único
Reemplazo (con un desencadenador previo o posterior) Escritura y lectura Transacción de varios elementos
Actualización e inserción (sin necesidad de un desencadenador previo o posterior) Escritura Transacción de un elemento único
Actualización e inserción (con un desencadenador previo o posterior) Escritura y lectura Transacción de varios elementos
Eliminación (sin necesidad de un desencadenador previo o posterior) Escritura Transacción de un elemento único
Eliminación (con un desencadenador previo o posterior) Escritura y lectura Transacción de varios elementos
Ejecutar procedimiento almacenado Escritura y lectura Transacción de varios elementos
El sistema inició la ejecución de un procedimiento de combinación Escritura Transacción de varios elementos
El sistema inició la ejecución de la eliminación de elementos basados en la expiración (TTL) de un elemento. Escritura Transacción de varios elementos
Lectura Lectura Transacción de un solo elemento
Fuente de cambios Lectura Transacción de varios elementos
Lectura paginada Lectura Transacción de varios elementos
Consulta paginada Lectura Transacción de varios elementos
Ejecución de UDF como parte de la consulta paginada Lectura Transacción de varios elementos

Transacciones de varios elementos

Azure Cosmos DB permite escribir procedimientos almacenados, desencadenadores y funciones definidas por el usuario y procedimientos de combinación en JavaScript. Azure Cosmos DB admite de forma nativa la ejecución de JavaScript dentro de su motor de base de datos. Puede registrar procedimientos almacenados, desencadenadores previos y posteriores, funciones definidas por el usuario (UDF) y procedimientos de combinación en un contenedor y ejecutarlos posteriormente de forma transaccional en el motor de base de datos de Azure Cosmos DB. La escritura de la lógica de la aplicación en JavaScript permite la expresión de forma natural del flujo de control, el ámbito de las variables, la asignación y la integración de primitivos de control de excepciones en transacciones de bases de datos directamente en el lenguaje JavaScript.

Los procedimientos almacenados basados en JavaScript, los desencadenadores, las UDF y los procedimientos de combinación se encapsulan en una transacción ACID ambiental con aislamiento de instantáneas en todos los elementos de la partición lógica. Durante su ejecución, si el programa JavaScript produce una excepción, se anula y se revierte toda la transacción. El modelo de programación resultante es sencillo, pero eficaz. Los desarrolladores de JavaScript obtienen un modelo de programación duradero al tiempo que siguen usando sus construcciones de lenguaje y primitivos de biblioteca que ya conocen.

La capacidad de ejecutar JavaScript directamente en el motor de base de datos proporciona rendimiento y la ejecución transaccional de las operaciones de base de datos en los elementos de un contenedor. Además, dado que el motor de base de datos de Azure Cosmos DB admite de forma nativa JSON y JavaScript, no hay ninguna discrepancia de impedancia entre los sistemas de tipos de una aplicación y la base de datos.

Control de simultaneidad optimista

El control de simultaneidad optimista (OCC) permite evitar las actualizaciones perdidas y las eliminaciones. Las operaciones simultáneas en conflicto están sujetas al bloqueo pesimista normal del motor de base de datos que hospeda la partición lógica que posee el elemento. Cuando dos operaciones simultáneas intentan actualizar la versión más reciente de un elemento dentro de una partición lógica, una de ellas gana y la otra produce un error. Sin embargo, si una o dos operaciones que intentan actualizar simultáneamente el mismo elemento habían leído previamente un valor anterior del elemento, la base de datos no sabe si el valor de lectura anterior por o ambas de las operaciones en conflicto era realmente el valor más reciente del elemento.

Afortunadamente, esta situación se puede detectar con el OCC antes de permitir que las dos operaciones entren en el límite de transacción dentro del motor de base de datos. El OCC protege los datos de sobrescribir accidentalmente los cambios realizados por otros usuarios. También impide que otros usuarios sobrescriban accidentalmente sus propios cambios.

Implementación del control de simultaneidad optimista mediante ETag y encabezados HTTP

Todos los elementos almacenados en un contenedor de Azure Cosmos DB tienen una propiedad _etag definida por el sistema. El servidor genera y actualiza automáticamente el valor de _etag cada vez que se actualiza el elemento. _etag se puede usar con el encabezado de solicitud if-match proporcionado por el cliente para permitir al servidor decidir si un elemento se puede actualizar de manera condicional. Si el valor del if-match encabezado coincide con el valor en el _etag del servidor, el elemento se actualiza. Si el valor del encabezado de solicitud if-match ya no es el actual, el servidor rechaza la operación con un mensaje de respuesta "HTTP 412 Precondition failure" (HTTP 412: error de condición previa). El cliente puede, posteriormente, volver a obtener el elemento para adquirir la versión actual de este en el servidor o invalidar la versión del elemento en el servidor con su propio valor _etag para el elemento. Además, _etag puede emplearse con el encabezado if-none-match para determinar si hay que volver a recuperar un recurso.

El valor _etag del elemento cambia cada vez que este se actualiza. En el caso de operaciones de reemplazo de elemento, if-match debe expresarse explícitamente como parte de las opciones de la solicitud. Para obtener un ejemplo, consulte el código de ejemplo en GitHub. Los valores _etag se comprueban implícitamente para todos los elementos escritos que toca el procedimiento almacenado. Si se detecta algún conflicto, el procedimiento almacenado revierte la transacción y produce una excepción. Con este método, se aplicarán de forma atómica todas las operaciones de escritura del procedimiento almacenado o ninguna de ellas. Esto constituye una señal para que la aplicación vuelva a aplicar las actualizaciones y reintente la solicitud original del cliente.

Control de simultaneidad optimista y distribución global

Las actualizaciones simultáneas de un elemento están sujetas al control de simultaneidad optimista mediante la capa del protocolo de comunicación de Azure Cosmos DB En el caso de las cuentas de Azure Cosmos DB configuradas para escrituras de una sola región, Azure Cosmos DB garantiza que la versión del lado cliente del elemento que está actualizando (o eliminando) es la misma que la versión del elemento en el contenedor de Azure Cosmos DB. Esto garantiza que las escrituras están protegidas frente a la sobrescritura accidental por escrituras de otros y viceversa. En un entorno de varios usuarios, el control de simultaneidad optimista le protege de eliminar o actualizar accidentalmente la versión incorrecta de un elemento. Por tanto, los elementos están protegidos contra los desastrosos problemas de "Actualización perdida" o "Eliminación perdida".

En una cuenta de Azure Cosmos DB configurada con escrituras de varias regiones, los datos se pueden confirmar de forma independiente en las regiones secundarias si su valor _etag coincide con el de los datos de la región local. Una vez que los nuevos datos se confirman localmente en una región secundaria, se combinan en el centro o en la región primaria. Si la directiva de resolución de conflictos combina los nuevos datos en la región central, estos datos se replican globalmente con el nuevo _etag. Si la directiva de resolución de conflictos rechaza los nuevos datos, la región secundaria se revierte a los datos originales y _etag.

Pasos siguientes

Obtenga más información sobre las transacciones de base de datos y el control de simultaneidad optimista: