Esta página describe la contención, la serialización y el aislamiento de datos transaccionales. Para ver ejemplos de códigos de transacciones, consulte transacciones y escrituras por lotes.
Transacciones y contención de datos
Para que una transacción tenga éxito, los documentos recuperados por sus operaciones de lectura no deben modificarse por operaciones externas a la transacción. Si otra operación intenta cambiar uno de esos documentos, esa operación entra en un estado de contención de datos con la transacción.
- Contención de datos
- Cuando dos o más operaciones compiten por controlar un mismo documento. Por ejemplo, una transacción podría requerir que un documento permanezca coherente mientras una operación simultánea intenta actualizar los valores de los campos de ese documento.
Cloud Firestore resuelve la contención de datos retrasando o fallando una de las operaciones. Las bibliotecas cliente de Cloud Firestore reintentan automáticamente las transacciones que fallan debido a la contención de datos. Después de un número finito de reintentos, la operación de transacción falla y devuelve un mensaje de error:
ABORTED: Too much contention on these documents. Please try again.
Al decidir qué operación fallar o retrasar, el comportamiento depende del tipo de biblioteca cliente.
Los SDK móviles/web utilizan controles de simultaneidad optimistas.
Las bibliotecas cliente del servidor utilizan controles de concurrencia pesimistas.
Contención de datos en los SDK móviles/web
Los SDK móviles/web (plataformas Apple, Android, Web, C++) utilizan controles de simultaneidad optimistas para resolver la contención de datos.
- Controles de concurrencia optimistas
- Basado en el supuesto de que no es probable que exista una contención de datos o que no es eficiente mantener bloqueos de la base de datos. Las transacciones optimistas no utilizan bloqueos de bases de datos para impedir que otras operaciones cambien los datos.
Los SDK móviles/web utilizan controles de concurrencia optimistas, porque pueden operar en entornos con alta latencia y una conexión de red poco confiable. Bloquear documentos en un entorno de alta latencia provocaría demasiados errores de contención de datos.
En los SDK móviles/web, una transacción realiza un seguimiento de todos los documentos que lee dentro de la transacción. La transacción completa sus operaciones de escritura solo si ninguno de esos documentos cambió durante la ejecución de la transacción. Si algún documento cambió, el controlador de transacciones vuelve a intentar la transacción. Si la transacción no puede obtener un resultado limpio después de algunos reintentos, la transacción falla debido a una contención de datos.
Contención de datos en las bibliotecas del cliente del servidor
Las bibliotecas cliente del servidor (C#, Go, Java, Node.js, PHP, Python, Ruby) utilizan controles de concurrencia pesimistas para resolver la contención de datos.
- Controles de concurrencia pesimistas
- Basado en el supuesto de que es probable que haya discordia en los datos. Las transacciones pesimistas utilizan bloqueos de bases de datos para evitar que otras operaciones modifiquen los datos.
Las bibliotecas cliente del servidor utilizan controles de concurrencia pesimistas porque suponen una latencia baja y una conexión confiable a la base de datos.
En las bibliotecas del cliente del servidor, las transacciones colocan bloqueos en los documentos que leen. El bloqueo de una transacción en un documento impide que otras transacciones, escrituras por lotes y escrituras no transaccionales cambien ese documento. Una transacción libera los bloqueos de sus documentos en el momento de la confirmación. También libera sus bloqueos si se agota el tiempo de espera o falla por algún motivo.
Cuando una transacción bloquea un documento, otras operaciones de escritura deben esperar a que la transacción libere su bloqueo. Las transacciones adquieren sus bloqueos en orden cronológico.
Aislamiento serializable
La contención de datos entre transacciones está estrechamente relacionada con los niveles de aislamiento de la base de datos. El nivel de aislamiento de una base de datos describe qué tan bien el sistema maneja los conflictos entre operaciones simultáneas. El conflicto proviene de los siguientes requisitos de la base de datos:
- Las transacciones requieren datos precisos y consistentes.
- Para utilizar los recursos de manera eficiente, las bases de datos ejecutan operaciones al mismo tiempo.
En sistemas con un nivel de aislamiento bajo, una operación de lectura dentro de una transacción podría leer datos inexactos de cambios no confirmados en una operación simultánea.
El aislamiento serializable define el nivel de aislamiento más alto. El aislamiento serializable significa que:
- Puede suponer que la base de datos ejecuta transacciones en serie.
- Las transacciones no se ven afectadas por cambios no comprometidos en operaciones concurrentes.
Esta garantía debe mantenerse incluso cuando la base de datos ejecuta múltiples transacciones en paralelo. La base de datos debe implementar controles de concurrencia para resolver conflictos que romperían esta garantía.
Cloud Firestore garantiza el aislamiento serializable de las transacciones. Las transacciones en Cloud Firestore se serializan y aíslan según el tiempo de confirmación.
Aislamiento serializable por tiempo de confirmación.
Cloud Firestore asigna a cada transacción un tiempo de confirmación que representa un único momento. Cuando Cloud Firestore confirma los cambios de una transacción en la base de datos, puedes asumir que todas las lecturas y escrituras dentro de la transacción se realizan exactamente en el momento de la confirmación.
La ejecución real de una transacción requiere cierto lapso de tiempo. La ejecución de una transacción comienza antes del momento de confirmación y la ejecución de múltiples operaciones puede superponerse. Cloud Firestore mantiene el aislamiento serializable y garantiza que:
- Cloud Firestore confirma las transacciones en orden según el tiempo de confirmación.
- Cloud Firestore aísla las transacciones de las operaciones simultáneas con un tiempo de confirmación posterior.
En el caso de conflicto de datos entre operaciones simultáneas, Cloud Firestore utiliza controles de concurrencia optimistas y pesimistas para resolver el conflicto.
Aislamiento dentro de una transacción
El aislamiento de transacciones también se aplica a operaciones de escritura dentro de una transacción. Las consultas y lecturas dentro de una transacción no ven los resultados de escrituras anteriores dentro de esa transacción. Incluso si modifica o elimina un documento dentro de una transacción, todas las lecturas de documentos en esa transacción devuelven la versión del documento en el momento de la confirmación, antes de las operaciones de escritura de la transacción. Las operaciones de lectura no devuelven nada si el documento no existía en ese momento.
Problemas con la contención de datos
Para obtener más información sobre la disputa de datos y cómo resolverla, consulte la página de solución de problemas .