Aislamiento y serialización de transacciones

En esta página se describen la contención, la serialización y el aislamiento de los datos transaccionales. Para ver muestras de código de transacciones, consulta el artículo Transacciones y escrituras en lotes.

Transacciones y conflictos de datos

Para que se realice correctamente una transacción, los documentos recuperados por sus operaciones de lectura deben permanecer sin modificaciones realizadas por operaciones fuera de la transacción. Si otra operación intenta modificar uno de esos documentos, quedará en un estado de contención de datos con la transacción.

Contención de datos
Cuando dos o más operaciones compiten para controlar el mismo documento. Por ejemplo, una transacción puede requerir que se mantenga la coherencia de un documento mientras una operación simultánea intenta actualizar los valores de los campos de ese documento.

Para resolver la contención de datos, Firestore retrasa o rechaza una de las operaciones. Las bibliotecas cliente de Firestore reintentan automáticamente las transacciones que fallan debido a la contención de datos. Después de una cantidad limitada de reintentos, la operación de transacción falla y se muestra un mensaje de error:

ABORTED: Too much contention on these documents. Please try again.

Cuando se decide qué operación se rechaza o retrasa, el comportamiento depende del tipo de biblioteca cliente.

  • Los SDK para dispositivos móviles y web usan controles de simultaneidad optimistas.

  • Las bibliotecas cliente del servidor usan controles de simultaneidad pesimistas.

Conflictos de datos en los SDK para dispositivos móviles y la Web

Los SDK para dispositivos móviles y web (iOS, Android, C++ y Web) usan controles de simultaneidad optimistas para resolver la contención de datos.

Controles de simultaneidad optimistas
Se basan en la suposición de que la contención de datos no es probable o no es eficiente para mantener los bloqueos de la base de datos. Las transacciones optimistas no usan bloqueos de bases de datos para impedir que otras operaciones modifiquen datos.

Los SDK para dispositivos móviles y web usan controles de simultaneidad optimistas porque pueden funcionar en entornos con latencia alta y conexiones de red poco confiables. Si se bloquean documentos en un entorno de latencia alta, ocurrirían demasiadas fallas por la contención de datos.

En los SDK para dispositivos móviles y web, las transacciones realizan un seguimiento de todos los documentos que se leen en ellas. Las transacciones completan sus operaciones de escritura solo si no se modificó ninguno de esos documentos durante su ejecución. Si cambió algún documento, el controlador de transacciones volverá a intentar la transacción. Si esta no puede obtener un resultado limpio después de algunos reintentos, fallará debido a la contención de datos.

Conflictos de datos en las bibliotecas cliente de servidor

Las bibliotecas cliente del servidor (C#, Go, Java, Node.js, PHP, Python y Ruby) usan controles de simultaneidad pesimistas para resolver la contención de datos.

Controles de simultaneidad pesimistas
Se basan en el supuesto de que la contención de datos es probable. Las transacciones pesimistas usan bloqueos de la base de datos para evitar que otras operaciones modifiquen los datos.

Las bibliotecas cliente del servidor usan controles de simultaneidad pesimistas porque suponen una latencia baja y una conexión confiable con la base de datos.

En las bibliotecas cliente del servidor, las transacciones aplican bloqueos en los documentos que leen. El bloqueo de una transacción en un documento evita que lo modifiquen otras transacciones, escrituras por lotes y escrituras no transaccionales. La transacción libera sus bloqueos de documentos en el momento de la confirmación y si se agota el tiempo de espera o falla por cualquier motivo.

Cuando una transacción bloquea un documento, otras operaciones de escritura deben esperar a que la transacción libere el bloqueo. Las transacciones aplican los bloqueos en orden cronológico.

Aislamiento serializable

La contención de datos entre transacciones se relaciona estrechamente con los niveles de aislamiento de las bases de datos. El nivel de aislamiento de una base de datos describe cómo controla el sistema los conflictos entre operaciones simultáneas. Estos provienen de los siguientes requisitos de bases de datos:

  • Las transacciones requieren datos exactos y coherentes.
  • Para usar recursos de manera eficiente, las bases de datos ejecutan operaciones de forma simultánea.

En los sistemas con un nivel de aislamiento bajo, una operación de lectura de una transacción puede leer datos inexactos de cambios no confirmados en una operación simultánea.

El aislamiento serializable es el nivel de aislamiento más alto. El aislamiento serializable implica lo siguiente:

  • Puedes suponer que la base de datos ejecuta transacciones en serie.
  • Los cambios no confirmados en operaciones simultáneas no afectan las transacciones.

Esta garantía debe mantenerse incluso mientras la base de datos ejecuta varias transacciones en paralelo. La base de datos debe implementar controles de simultaneidad para resolver los conflictos que podrían afectar esta garantía.

Firestore garantiza el aislamiento serializable de las transacciones. Las transacciones de Firestore se serializan y aíslan según el tiempo de confirmación.

Aislamiento serializable según el tiempo de confirmación

Firestore asigna a cada transacción un tiempo de confirmación que representa un momento específico. Cuando Firestore confirma los cambios de una transacción en la base de datos, puedes suponer que todas las lecturas y escrituras de la transacción se realizan exactamente en el momento de la confirmación.

La ejecución real de una transacción requiere un intervalo de tiempo. La ejecución de una transacción comienza antes del tiempo de confirmación y podría superponerse a la ejecución de varias operaciones. Firestore mantiene el aislamiento serializable y garantiza lo siguiente:

  • Firestore confirma las transacciones en orden y según el tiempo de confirmación.
  • Firestore aísla las transacciones de las operaciones simultáneas con un tiempo de confirmación posterior.

Firestore usa controles de simultaneidad optimistas y pesimistas para resolver la contención de datos entre operaciones simultáneas.

Aislamiento en una transacción

El aislamiento de transacciones también se aplica a las operaciones de escritura de una transacción. Las consultas y lecturas de una transacción no ven los resultados de las operaciones de escritura anteriores que se realizan en ella. Incluso si modificas o borras un documento en una transacción, todas las operaciones de lectura de documentos de esa transacción muestran la versión del documento correspondiente al momento de la confirmación, antes de que se apliquen las operaciones de escritura de la transacción. Las operaciones de lectura no muestran nada si el documento no existía en ese momento.