Compartir a través de


Transacciones y control de simultaneidad optimista

Las transacciones de base de datos proporcionan un modelo de programación seguro y predecible para tratar los cambios simultáneos 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 totalmente compatibles con ACID (atomicidad, coherencia, aislamiento, durabilidad), incluido 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 escritura (actualización de uno o varios elementos dentro 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
Insertar (sin un desencadenador previo o posterior) Escribir Transacción de un solo elemento
Insertar (con un desencadenador previo y posterior) Escritura y lectura Transacción de varios elementos
Reemplazar (sin un desencadenador previo o posterior) Escribir Transacción de un solo elemento
Reemplazar (por un desencadenador previo y posterior) Escritura y lectura Transacción de varios elementos
Upsert (sin un desencadenador previo o posterior) Escribir Transacción de un solo elemento
Upsert (con un desencadenador previo y posterior) Escritura y lectura Transacción de varios elementos
Eliminar (sin un desencadenador previo o posterior) Escribir Transacción de un solo elemento
Eliminar (con un desencadenador previo y posterior) Escritura y lectura Transacción de varios elementos
Ejecutar procedimiento almacenado Escritura y lectura Transacción de varios elementos
Ejecución iniciada por el sistema de un procedimiento de combinación Escribir Transacción de varios elementos
El sistema inició la ejecución de la eliminación de elementos basándose en el tiempo de vida (TTL) de cada uno Escribir Transacción de varios elementos
Read Read Transacción de un solo elemento
Fuente de cambios Read Transacción de varios elementos
Lectura paginada Read Transacción de varios elementos
Consulta paginada Read Transacción de varios elementos
Ejecutar UDF como parte de la consulta paginada Read 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. Escribir lógica de aplicación en JavaScript permite la expresión natural del flujo de control, el ámbito de variables, la asignación y la integración de primitivos de control de excepciones dentro de las transacciones de base de datos directamente en el lenguaje JavaScript.

Los procedimientos almacenados, desencadenadores, UDF y procedimientos de combinación basados en JavaScript se encapsulan dentro de una transacción ACID ambiente 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 mientras siguen usando sus conocidas construcciones de lenguaje y primitivos de biblioteca.

La capacidad de ejecutar JavaScript directamente dentro del motor de base de datos proporciona rendimiento y 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 concurrentes y en conflicto están sujetas al bloqueo pesimista normal del motor de base de datos hospedado por la partición lógica que es propietaria del 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 tus datos para evitar que los cambios realizados por otros usuarios se sobrescriban accidentalmente. También impide que otros usuarios sobrescriban accidentalmente sus propios cambios.

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

Cada elemento almacenado en un contenedor de Azure Cosmos DB tiene una propiedad definida por _etag 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 proporcionado if-match por el cliente para permitir que el servidor decida si un elemento se puede actualizar condicionalmente. Si el valor del encabezado if-match coincide con el valor en el _etag servidor, el elemento se actualiza. Si el valor del if-match encabezado de solicitud ya no está actualizado, el servidor rechaza la operación con un mensaje de respuesta "Error de condición previa HTTP 412". A continuación, el cliente puede volver a capturar el elemento para adquirir la versión actual del elemento en el servidor o invalidar la versión del elemento en el servidor con su propio _etag valor para el elemento. Además, _etag se puede usar con la cabecera if-none-match para determinar si se necesita una recaptura de un recurso.

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

Control de simultaneidad optimista y distribución global

Las actualizaciones simultáneas de un elemento están sujetas al OCC por la capa de 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 de ser accidentalmente sobrescritas por las 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 lo tanto, los elementos están protegidos contra los problemas de "actualización perdida" o "eliminación perdida".

En una cuenta de Azure Cosmos DB configurada con escrituras multirregionales, los datos se pueden confirmar de forma independiente en regiones secundarias si su _etag coincide con el de los datos en 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 fusiona 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: