La siguiente página enumera algunas consideraciones de producción para ejecutar transacciones. Estos se aplican tanto si ejecuta transacciones en conjuntos de réplicas como en clústeres fragmentados. Para ejecutar transacciones en clústeres fragmentados, consulte también Consideraciones de producción (clústeres fragmentados) para obtener consideraciones adicionales que son específicas de los clústeres fragmentados.
-
En la versión 4.0 , MongoDB admite transacciones de múltiples documentos en conjuntos de réplicas.
-
En la versión 4.2 , MongoDB introduce transacciones distribuidas, que agrega soporte para transacciones de múltiples documentos en clústeres fragmentados e incorpora el soporte existente para transacciones de múltiples documentos en conjuntos de réplicas.
Para usar transacciones en implementaciones de MongoDB 4.2 (conjuntos de réplicas y clústeres fragmentados), los clientes deben usar controladores de MongoDB actualizados para MongoDB 4.2.
NOTA
Transacciones distribuidas y transacciones de varios documentos
A partir de MongoDB 4.2, los dos términos son sinónimos. Las transacciones distribuidas se refieren a transacciones de varios documentos en grupos fragmentados y conjuntos de réplicas. Las transacciones de múltiples documentos (ya sea en clústeres fragmentados o conjuntos de réplicas) también se conocen como transacciones distribuidas a partir de MongoDB 4.2.
Para usar transacciones, featureCompatibilityVersion para todos los miembros de la implementación debe ser al menos:
Despliegue | Mínimo featureCompatibilityVersion |
---|---|
Conjunto de réplicas | 4.0 |
Clúster fragmentado | 4.2 |
Para verificar el fCV de un miembro, conéctese al miembro y ejecute el siguiente comando:
db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
Para obtener más información, consulte la setFeatureCompatibilityVersion
página de referencia.
De forma predeterminada, una transacción debe tener un tiempo de ejecución de menos de un minuto. Puede modificar este límite utilizando transactionLifetimeLimitSeconds
para las mongod
instancias. Para los clústeres fragmentados, el parámetro debe modificarse para todos los miembros del conjunto de réplicas de fragmentos. Las transacciones que exceden este límite se consideran vencidas y serán canceladas por un proceso de limpieza periódico.
Para los clústeres fragmentados, también puede especificar un maxTimeMS
límite en commitTransaction
. Para obtener más información, consulte Límite de tiempo de transacciones de clústeres fragmentados .
A partir de la versión 4.2,MongoDB crea tantas entradas de registro de operaciones como sea necesario para encapsular todas las operaciones de escritura en una transacción, en lugar de una sola entrada para todas las operaciones de escritura en la transacción. Esto elimina el límite de tamaño total de 16 MB para una transacción impuesto por la entrada única del registro de operaciones para todas sus operaciones de escritura. Aunque se elimina el límite de tamaño total, cada entrada de registro de operaciones aún debe estar dentro del límite de tamaño de documento BSON de 16 MB.En la versión 4.0,MongoDB crea una única entrada de registro de operaciones (registro de operaciones) en el momento de la confirmación si la transacción contiene alguna operación de escritura. Es decir, las operaciones individuales en las transacciones no tienen una entrada de registro correspondiente. En cambio, una sola entrada de registro de operaciones contiene todas las operaciones de escritura dentro de una transacción. La entrada del registro de operaciones para la transacción debe estar dentro del límite de tamaño del documento BSON de 16 MB.
Para evitar que la presión de la caché de almacenamiento afecte negativamente al rendimiento:
- Cuando abandone una transacción, anótela.
- Cuando encuentre un error durante una operación individual en la transacción, cancele y vuelva a intentar la transacción.
Las transactionLifetimeLimitSeconds
asegura también que expiraron las transacciones son abortados periódicamente a la presión de almacenamiento caché aliviar.
- Si se ejecuta con control de acceso , debe tener privilegios para las operaciones en la transacción .
- Si se ejecuta con auditoría , las operaciones en una transacción abortada aún se auditan. Sin embargo, no hay ningún evento de auditoría que indique que la transacción se anuló.
No puede ejecutar transacciones en un clúster fragmentado que tiene un fragmento con writeConcernMajorityJournalDefault
establecido en false
(como un fragmento con un miembro votante que usa el motor de almacenamiento en memoria ).
Las transacciones cuyas operaciones de escritura abarcan varios fragmentos generarán errores y se cancelarán si alguna operación de transacción lee o escribe en un fragmento que contiene un árbitro.
Consulte también Arquitectura de árbitro primario-secundario de 3 miembros para conocer las restricciones de transacción en fragmentos que han deshabilitado la mayoría de interés de lectura.
Para un conjunto de réplicas de tres miembros con una arquitectura de árbitro primario-secundario (PSA) o un clúster fragmentado con fragmentos de PSA de tres miembros, es posible que haya desactivado la preocupación de lectura "mayoría" para evitar la presión de la caché.En clústeres fragmentados,
-
Si una transacción involucra un fragmento que ha inhabilitado la preocupación de lectura "mayoría" , no puede utilizar la preocupación de lectura
"snapshot"
para la transacción. Solo puede usar la preocupación de lectura"local"
o"majority"
para la transacción. Si usa la preocupación de lectura"snapshot"
, la transacción se produce un error y se cancela.readConcern level 'snapshot' is not supported in sharded clusters when enableMajorityReadConcern=false.
-
Las transacciones cuyas operaciones de escritura abarcan varios fragmentos generarán errores y se abortarán si alguna de las operaciones de lectura o escritura de la transacción involucra un fragmento que ha deshabilitado el problema de lectura
"majority"
.
En el juego de réplicas,
Puede especificar la preocupación de lectura "local"
o "majority"
, o "snapshot"
incluso en el conjunto de réplicas tiene desactivado lectura preocupación "mayoría" .
Sin embargo, si planea realizar la transición a un clúster fragmentado con fragmentos mayoritarios de preocupación de lectura deshabilitados, es posible que desee evitar el uso de la preocupación de lectura "snapshot"
.
CONSEJO
Para comprobar si la preocupación de lectura "mayoría" está deshabilitada, puede ejecutar db.serverStatus()
las mongod
instancias y marcar el storageEngine.supportsCommittedReads
campo. Si false
, lea la preocupación "mayoría" está deshabilitada.
CONSEJO
Ver también:
De forma predeterminada, las transacciones esperan hasta 5
milisegundos para adquirir los bloqueos requeridos por las operaciones en la transacción. Si la transacción no puede adquirir sus bloqueos requeridos dentro de los 5
milisegundos, la transacción se aborta.
Las transacciones liberan todos los bloqueos al abortar o confirmar.
CONSEJO
Al crear o eliminar una colección inmediatamente antes de iniciar una transacción, si se accede a la colección dentro de la transacción, emita la operación de creación o eliminación con preocupación de escritura "majority"
para garantizar que la transacción pueda adquirir los bloqueos necesarios.
Puede utilizar el maxTransactionLockRequestTimeoutMillis
parámetro para ajustar cuánto tiempo esperan las transacciones para adquirir bloqueos. El aumento maxTransactionLockRequestTimeoutMillis
permite que las operaciones en las transacciones esperen el tiempo especificado para adquirir los bloqueos requeridos. Esto puede ayudar a evitar abortos de transacciones en adquisiciones de bloqueos simultáneos momentáneos, como operaciones de metadatos de ejecución rápida. Sin embargo, esto posiblemente podría retrasar la interrupción de las operaciones de transacción bloqueadas.
También puede utilizar el tiempo de espera específico de la operación estableciendo maxTransactionLockRequestTimeoutMillis
en -1
.
Si hay una transacción de varios documentos en curso, las nuevas operaciones de DDL que afectan a las mismas bases de datos o colecciones esperan detrás de la transacción. Si bien existen estas operaciones DDL pendientes, las nuevas transacciones que acceden a las mismas bases de datos o colecciones que las operaciones DDL pendientes no pueden obtener los bloqueos requeridos y se abortarán después de esperar maxTransactionLockRequestTimeoutMillis
. Además, las operaciones nuevas que no sean transacciones y que accedan a las mismas bases de datos o colecciones se bloquearán hasta que alcancen su maxTimeMS
límite.
Considere los siguientes escenarios:
Operación DDL que requiere un bloqueo de colección
Mientras una transacción en curso está realizando varias operaciones CRUD en la employees
colección en la hr
base de datos, un administrador emite la db.collection.createIndex()
operación DDL contra la employees
colección. createIndex()
requiere un candado de colección exclusivo en la colección.
Hasta que se complete la transacción en curso, la createIndex()
operación debe esperar para obtener el bloqueo. Cualquier transacción nueva que afecte la employees
colección y comience mientras createIndex()
está pendiente debe esperar hasta que se createIndex()
complete.
La createIndex()
operación DDL pendiente no afecta las transacciones en otras colecciones de la hr
base de datos. Por ejemplo, una nueva transacción en la contractors
colección en la hr
base de datos puede comenzar y completarse normalmente.
Operación DDL que requiere un bloqueo de base de datos
Mientras una transacción en curso está realizando varias operaciones CRUD en la employees
colección en la hr
base de datos, un administrador emite la collMod
operación DDL contra la contractors
colección en la misma base de datos. collMod
requiere un bloqueo de base de datos en la hr
base de datos principal .
Hasta que se complete la transacción en curso, la collMod
operación debe esperar para obtener el bloqueo. Cualquier nueva transacción que afecte la hr
base de datos o cualquiera de sus colecciones y comience mientras collMod
está pendiente debe esperar hasta que se collMod
complete.
En cualquier escenario, si la operación DDL permanece pendiente durante más de maxTransactionLockRequestTimeoutMillis
, las transacciones pendientes que esperan detrás de esa operación se cancelan. Es decir, el valor de maxTransactionLockRequestTimeoutMillis
debe cubrir al menos el tiempo necesario para que se complete la transacción en curso y la operación DDL pendiente.
CONSEJO
Ver también:
- __Transacciones en curso y conflictos de escritura__
- __Transacciones en curso y lecturas obsoletas__
- __¿Qué comandos administrativos bloquean una base de datos?__
- __¿Qué comandos administrativos bloquean una colección?__
Si una transacción está en progreso y una escritura fuera de la transacción modifica un documento que luego una operación en la transacción intenta modificar, la transacción se aborta debido a un conflicto de escritura.
Si una transacción está en curso y se ha bloqueado para modificar un documento, cuando una escritura fuera de la transacción intenta modificar el mismo documento, la escritura espera hasta que finaliza la transacción.
CONSEJO
Ver también:
Las operaciones de lectura dentro de una transacción pueden devolver datos obsoletos. Es decir, no se garantiza que las operaciones de lectura dentro de una transacción vean escrituras realizadas por otras transacciones comprometidas o escrituras no transaccionales. Por ejemplo, considere la siguiente secuencia: 1) una transacción está en curso 2) una escritura fuera de la transacción elimina un documento 3) una operación de lectura dentro de la transacción puede leer el documento ahora eliminado ya que la operación está usando una instantánea desde antes de la escritura.
Para evitar lecturas obsoletas dentro de las transacciones de un solo documento, puede utilizar el db.collection.findOneAndUpdate()
método. Por ejemplo:
session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );
employeesCollection = session.getDatabase("hr").employees;
employeeDoc = employeesCollection.findOneAndUpdate(
{ _id: 1, employee: 1, status: "Active" },
{ $set: { employee: 1 } },
{ returnNewDocument: true }
);
- Si el documento del empleado ha cambiado fuera de la transacción, la transacción se cancela.
- Si el documento del empleado no ha cambiado, la transacción devuelve el documento y lo bloquea.
La migración de fragmentos adquiere bloqueos de colección exclusivos durante determinadas etapas.
Si una transacción en curso tiene un bloqueo en una colección y se inicia una migración de fragmentos que implica esa recopilación, estas etapas de migración deben esperar a que la transacción libere los bloqueos de la colección, lo que afectará el rendimiento de las migraciones de fragmentos.
Si una migración de fragmentos se entrelaza con una transacción (por ejemplo, si una transacción comienza mientras una migración de fragmentos ya está en curso y la migración se completa antes de que la transacción bloquee la colección), la transacción se produce un error durante la confirmación y se cancela.
Dependiendo de cómo se intercalen las dos operaciones, algunos errores de muestra incluyen (los mensajes de error se han abreviado):
an error from cluster data placement change ... migration commit in progress for <namespace>
Cannot find shardId the chunk belonged to at cluster time ...
CONSEJO Ver tambiénshardingStatistics.countDonorMoveChunkLockTimeout
__
Durante la confirmación de una transacción, las operaciones de lectura externas pueden intentar leer los mismos documentos que serán modificados por la transacción. Si la transacción escribe en varios fragmentos, durante el intento de confirmación en los fragmentos
- Exterior lee que el uso leyó preocupación
"snapshot"
o"linearizable"
, o son parte de las sesiones causalmente consistentes (es decir, incluyen afterClusterTime ) espera para todas las escrituras de una transacción para que sea visible. - Las lecturas externas que utilizan otras preocupaciones de lectura no esperan a que todas las escrituras de una transacción sean visibles, sino que leen la versión anterior a la transacción de los documentos disponibles.
Para usar transacciones en implementaciones de MongoDB 4.2 (conjuntos de réplicas y clústeres fragmentados), los clientes deben usar controladores de MongoDB actualizados para MongoDB 4.2.
En clústeres fragmentados con varias mongos
instancias, la realización de transacciones con controladores actualizados para MongoDB 4.0 (en lugar de MongoDB 4.2) fallará y puede generar errores, que incluyen:
NOTA: Su controlador puede devolver un error diferente. Consulte la documentación de su controlador para obtener más detalles.
Código de error | Mensaje de error |
---|---|
251 | cannot continue txnId -1 for session ... with txnId 1 |
50940 | cannot commit with no participants |
CONSEJO Ver también: