Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Transacciones

En MongoDB, una operación sobre un solo documento es atómica. Como puedes utilizar documentos incrustados y arreglos para captar relaciones entre datos en una sola estructura de documento en lugar de normalizar a través de varios documentos y colecciones, las transacciones multidocumento no son necesarias para muchos casos de uso prácticos.

Para situaciones que requieren atomicidad de operaciones en múltiples documentos, MongoDB admite transacciones. Puedes utilizar transacciones en varias operaciones, colecciones, bases de datos, documentos y particiones.

Utilice el selector de lenguaje para establecer el lenguaje del siguiente ejemplo.

Tip

Para un ejemplo en mongosh, consulta mongosh Ejemplo.

Para situaciones que requieren atomicidad de las lecturas y escrituras en varios documentos (en una sola colección o en varias), MongoDB admite transacciones distribuidas, incluidas las transacciones en sets de réplica y clústeres fragmentados.

Las transacciones distribuidas son atómicas:

  • Las transacciones aplican todos los cambios de datos o los revierten.

  • Si una transacción se confirma, todos los cambios de datos realizados en la transacción se guardan y son visibles fuera de la transacción.

    Hasta que se produzca la confirmación de una transacción, los cambios de datos realizados en la transacción no son visibles fuera de la transacción.

    Sin embargo, cuando una transacción se guarda en múltiples fragmentos, no todas las operaciones de lectura externas necesitan esperar a que el resultado de la transacción confirmada sea visible en todos los fragmentos. Por ejemplo, si se confirma una transacción y la escritura 1 es visible en el fragmento A, pero la escritura 2 aún no es visible en el fragmento B, una lectura externa con el nivel de consistencia de lectura "local" puede leer los resultados de la escritura 1 sin ver la escritura 2.

  • Cuando una transacción se aborta, todos los cambios de datos realizados en la transacción se descartan sin llegar a ser visibles.

Importante

En la mayoría de los casos, una transacción distribuida incurre en un costo de rendimiento mayor que las escrituras de documentos individuales, y la disponibilidad de transacciones distribuidas no debería ser un sustituto para un diseño de esquema efectivo. Para muchos casos, el modelo de datos desnormalizado (documento incrustado y matrices) seguirá siendo óptimo para tus datos y casos de uso. Es decir, en muchos casos, modelar tus datos de forma adecuada minimizará la necesidad de transacciones distribuidas.

Para consideraciones adicionales sobre el uso de transacciones (como el límite de tiempo de ejecución y el límite de tamaño del oplog), consulta también las consideraciones de producción.

Las transacciones pueden ser utilizadas en múltiples operaciones, colecciones, bases de datos, documentos y particiones.

Para las transacciones:

  • Puedes crear colecciones e índices en transacciones. Para obtener más detalles, consulta Crear colecciones e índices en una transacción

  • Las colecciones utilizadas en una transacción pueden encontrarse en diferentes bases de datos.

    Nota

    No puedes crear nuevas colecciones en transacciones de escritura entre particiones. Por ejemplo, si guardas en una colección existente en una partición y creas implícitamente una colección en una partición diferente, MongoDB no puede realizar ambas operaciones en la misma transacción.

  • No se puede escribir en colecciones con tamaño fijo.

  • No puedes usar el nivel de consistencia de lectura "snapshot" al leer de una colección con tamaño fijo. (A partir de MongoDB 5.0)

  • No puedes leer ni escribir en colecciones en las bases de datos config, admin o local.

  • No se puede escribir en las colecciones de system.*.

  • No puedes devolver el plan de query de las operaciones admitidas usando explain o comandos similares.

  • Para los cursores creados fuera de una transacción, no puedes llamar a getMore dentro de la transacción.

  • Para los cursores creados en una transacción, no puedes llamar a getMore fuera de la transacción.

  • No se puede especificar el comando como la killCursors primera operación de una transacción. Además, si se ejecuta el killCursors comando dentro de una transacción, el servidor detiene inmediatamente los cursores especificados. No espera a que la transacción se confirme.

Para obtener una lista de las operaciones no admitidas en las transacciones, consulta Operaciones restringidas.

Tip

Al crear o descartar una colección inmediatamente antes de iniciar una transacción, si se accede a la colección dentro de la transacción, realice la operación de creación o descarte con el nivel de confirmación de escritura "majority" para asegurarse de que la transacción pueda adquirir los bloqueos necesarios.

Puedes realizar las siguientes operaciones en una transacción si no se trata de una transacción de escritura entre fragmentos:

  • Crea colecciones.

  • Crea índices en nuevas colecciones vacías que se hayan creado anteriormente en la misma transacción.

Al crear una colección dentro de una transacción:

Cuando cree un índice dentro de una transacción [1], el índice que se va a crear debe estar en uno de los siguientes:

  • una colección inexistente. La colección se crea como parte de la operación.

  • una nueva colección vacía creada anteriormente en la misma transacción.

[1] También puede ejecutar db.collection.createIndex() y db.collection.createIndexes() en índices existentes para comprobar su existencia. Estas operaciones se completan con éxito sin crear el índice.
  • No puedes crear nuevas colecciones en transacciones de escritura entre particiones. Por ejemplo, si guardas en una colección existente en una partición y creas implícitamente una colección en una partición diferente, MongoDB no puede realizar ambas operaciones en la misma transacción.

  • No se puede usar la etapa $graphLookup dentro de una transacción durante el direccionamiento a una colección fragmentada.

  • Para la creación explícita de una colección o un índice dentro de una transacción, el nivel de consistencia de lectura de la transacción debe ser "local".

    Para crear explícitamente colecciones e índices, utiliza los siguientes comandos y métodos:

Para realizar una operación de conteo dentro de una transacción, utilice la etapa de agregación $count o la etapa de agregación $group (con una expresión $sum).

Los controladores de MongoDB proporcionan una API a nivel de colección countDocuments(filter, options) como un método asistente que utiliza el $group con una expresión $sum para realizar un conteo.

mongosh proporciona el método asistente db.collection.countDocuments() que utiliza $group con una expresión $sum para realizar un conteo.

Para realizar una operación específica dentro de una transacción:

  • Para colecciones no fragmentadas, puedes utilizar el método db.collection.distinct() o el comando distinct, así como la canalización de agregación con la etapa $group.

  • Para colecciones fragmentadas, no puede utilizar el método db.collection.distinct() ni el comando distinct.

    Para encontrar los valores distintos de una colección fragmentada, utilice la canalización de agregación con la etapa $group en su lugar. Por ejemplo:

    • En lugar de db.coll.distinct("x"), utilice

      db.coll.aggregate([
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])
    • En lugar de db.coll.distinct("x", { status: "A" }), utilice:

      db.coll.aggregate([
      { $match: { status: "A" } },
      { $group: { _id: null, distinctValues: { $addToSet: "$x" } } },
      { $project: { _id: 0 } }
      ])

    El pipeline devuelve un cursor a un documento:

    { "distinctValues" : [ 2, 3, 1 ] }

    Itere el cursor para acceder al documento de resultados.

Los comandos informativos, como hello, buildInfo, connectionStatus (y sus métodos asistentes) están permitidos en las transacciones; sin embargo, no pueden ser la primera operación de la transacción.

Las siguientes operaciones no están permitidas en las transacciones:

  • Las transacciones están asociadas a una sesión.

  • Puede tener como máximo una transacción abierta a la vez para una sesión.

  • Cuando se utilizan los drivers, cada operación en la transacción debe estar asociada a la sesión. Se debe consultar la documentación específica del driver para conseguir más detalles.

  • Si una sesión termina y tiene una transacción abierta, la transacción se abortará.

Las operaciones en una transacción utilizan la preferencia de lectura a nivel de transacción.

Usando los drivers, se puede establecer la preferencia de lectura a nivel de transacción al inicio de la transacción:

  • Si la preferencia de lectura a nivel de transacción no está establecida, la transacción utiliza la preferencia de lectura a nivel de sesión.

  • Si la preferencia de lectura a nivel de transacción y la de nivel de sesión no están establecidas, la transacción utiliza la preferencia de lectura a nivel de cliente. Por defecto, la preferencia de lectura a nivel de cliente es primary.

Transacciones que contienen operaciones de lectura deben usar la preferencia de lectura primary. Todas las operaciones en una transacción determinada deben dirigirse al mismo nodo.

Las operaciones en una transacción utilizan el nivel de consistencia de lectura de la transacción. Esto significa que un nivel de consistencia de lectura establecido a nivel de colección y base de datos se ignora dentro de la transacción.

Puede establecer el nivel de consistencia de lectura a nivel de transacción al inicio de la transacción.

  • Si el nivel de consistencia de lectura a nivel de transacción no está establecido, el nivel de consistencia de lectura a nivel de transacción por defecto se ajusta al nivel de consistencia de lectura a nivel de sesión.

  • Si el nivel de consistencia de lectura de transacción y el de sesión no están configurados, el nivel de consistencia de lectura de transacción por defecto es el nivel de consistencia de lectura de cliente. Por defecto, el nivel de consistencia de lectura de es "local" para las lecturas en el primario. Véase también:

Las transacciones soportan los siguientes niveles de consistencia de lectura:

  • El nivel de consistencia de lectura "local" devuelve los datos más recientes disponibles del nodo, pero puede ser revertido.

  • En un set de réplicas, incluso si una transacción utiliza un nivel de consistencia de lectura de local, es posible que observe un aislamiento de lectura más fuerte, donde la operación lee desde un snapshot en el punto en el que se abrió la transacción.

  • Para las transacciones en un clúster, el nivel de consistencia de lectura "local" no puede garantizar que los datos provengan de la misma vista de snapshot en todos los fragmentos. Si se requiere el aislamiento de snapshot, utiliza un "snapshot" nivel de consistencia de lectura.

  • Puedes crear colecciones e índices dentro de una transacción. Si creas explícitamente una colección o un índice, la transacción debe usar el nivel de consistencia de lectura "local". Si creas implícitamente una colección, puedes utilizar cualquiera de los niveles de consistencia de lectura disponibles para las transacciones.

  • Si la transacción se confirma con el nivel de confirmación de escritura "mayoría", el nivel de consistencia de lectura "majority" devuelve datos que hayan sido reconocidos por la mayoría de los miembros del set de réplicas y no se pueden revertir. De lo contrario, el nivel de consistencia de lectura "majority" no ofrece garantías de que las operaciones de lectura accedan a datos comprometidos por la mayoría.

  • Para las transacciones en un clúster fragmentado, el nivel de consistencia de lectura "majority" no puede garantizar que los datos provengan de la misma vista de snapshot en todos los fragmentos. Si se requiere el aislamiento de snapshot, utiliza el nivel de consistencia de lectura "snapshot".

Las transacciones utilizan el nivel de confirmación de escritura (write concern) a nivel de transacción para confirmar las operaciones de escritura. Las operaciones de escritura dentro de las transacciones deben ejecutarse sin una especificación explícita de nivel de confirmación de escritura (write concern) y utilizar el nivel de confirmación de escritura (write concern) por defecto. En el momento de la confirmación, las escrituras se confirman utilizando el nivel de confirmación de escritura (write concern) de la transacción.

Tip

No establezca explícitamente el nivel de confirmación de escritura para las operaciones de escritura individuales dentro de una transacción. Configurar niveles de confirmación de escritura para las operaciones de escritura individuales dentro de una transacción genera un error.

Puede establecer el nivel de confirmación de escritura a nivel de transacción al inicio de la transacción:

  • Si el nivel de confirmación de escritura a nivel de transacción no está establecido, se utiliza por defecto el nivel de confirmación de escritura a nivel de sesión para la confirmación.

  • Si el nivel de confirmación de escritura a nivel de transacción y el nivel de confirmación de escritura a nivel de sesión no están configurados, el nivel de confirmación de escritura a nivel de transacción por defecto es el nivel de confirmación de escritura a nivel de cliente de:

Las transacciones tienen soporte para todos los valores de w de nivel de confirmación de escritura, incluidos:

  • El nivel de confirmación de escritura w: 1 devuelve un reconocimiento después de que la confirmación se haya aplicado al primario.

    Importante

    Cuando se realiza una confirmación w: 1, la transacción puede revertirse si hay una conmutación por error.

  • Cuando confirma el nivel de confirmación de escritura w: 1, el nivel de consistencia de lectura a nivel de transacción "majority" no ofrece garantías de que las operaciones de lectura en la transacción lean datos confirmados por la mayoría.

  • Cuando se confirma el nivel de confirmación de escritura w: 1, el nivel de consistencia de lectura a nivel de transacción "snapshot" no proporciona garantías de que las operaciones de lectura en la transacción hayan utilizado una snapshot de los datos confirmados por la mayoría.

  • El nivel de confirmación de escritura w: "majority" devuelve un reconocimiento después de que la confirmación se haya aplicado a la mayoría de los miembros con derecho a voto.

  • Cuando se confirma el nivel de confirmación de escritura w: "majority", el nivel de consistencia de lectura a nivel de transacción "majority" garantiza que las operaciones hayan leído datos confirmados por la mayoría. Para las transacciones en clústeres particionados, esta vista de los datos confirmados por la mayoría no se sincroniza entre los fragmentos.

  • Cuando se confirma el nivel de confirmación de escritura w: "majority", el nivel de consistencia de lectura a nivel de transacción "snapshot" ofrece garantías de que las operaciones han leído de una snapshot sincronizada de datos confirmados por la mayoría.

Nota

Independientemente del nivel de confirmación de escritura especificado para la transacción, la operación de confirmación para una transacción de clúster incluye algunas partes que utilizan el nivel de confirmación de escritura {w: "majority", j: true}.

El parámetro del servidor coordinateCommitReturnImmediatelyAfterPersistingDecision controla cuándo se devuelven las decisiones de confirmación de transacción al cliente.

El parámetro fue introducido en MongoDB 5.0 con un valor por defecto de true. En MongoDB 6.1, el valor por defecto cambia a false.

Cuando coordinateCommitReturnImmediatelyAfterPersistingDecision es false, el coordinador de transacciones de partición espera a que todos los miembros reconozcan una confirmación de transacción antes de devolver la decisión de confirmación al cliente.

Si especificas un "majority" nivel de confirmación de escritura (write concern) para las operaciones de escritura y la operación no se replica a la mayoría calculada de los miembros del conjunto de réplicas antes de que devuelva una respuesta, entonces los datos eventualmente se replican o se revierten. Consulta wtimeout.

Independientemente del nivel de confirmación de escritura especificado para la transacción, el controlador aplica w: "majority" como nivel de confirmación de escritura al volver a intentar commitTransaction.

Las siguientes secciones describen los requisitos y consideraciones de las transacciones que varían según el tipo de implementación, el motor de almacenamiento y la versión de MongoDB.

Para transacciones en entornos de producción, consulte Consideraciones de producción. Además, para clústeres fragmentados, consulte Consideraciones de producción (Clústeres fragmentados).

No puedes cambiar una clave de fragmentación mediante una transacción si el set de réplicas tiene un árbitro. Los árbitros no pueden participar en las operaciones de datos requeridas para las transacciones de múltiples fragmentos.

Las transacciones cuyas operaciones de escritura abarcan varios fragmentos generarán un error y se abortarán si alguna operación de transacción lee o escribe en una partición que contiene un árbitro.

No puedes ejecutar transacciones en un clúster que tenga una partición con writeConcernMajorityJournalDefault configurado en false (como una partición con un nodo votante que utiliza el motor de almacenamiento en memoria).

Nota

Independientemente del nivel de confirmación de escritura especificado para la transacción, la operación de confirmación para una transacción de clúster incluye algunas partes que utilizan el nivel de confirmación de escritura {w: "majority", j: true}.

Para obtener el estado de la transacción y las métricas, utilice los siguientes métodos:

Origen
Devuelve

Devuelve las métricas de transacciones.

Algunos campos de respuesta serverStatus no se devuelven en los clústeres gratuitos o clústeres Flex de MongoDB Atlas. Para obtener más información, consulta Comandos Limitados en la documentación de MongoDB Atlas.

$currentOp Aggregation Pipeline

Devuelve:

db.currentOp() método
currentOp comando

Devuelve:

mongod y mensajes de registro de mongos

Incluye información sobre las transacciones lentas (que son transacciones que superan el umbral de operationProfiling.slowOpThresholdMs) en el componente de registro TXN.

Para utilizar transacciones, la featureCompatibilityVersion de todos los miembros de la implementación debe ser al menos:

Implementación
Mínimo featureCompatibilityVersion

Set de réplicas

4.0

Clúster fragmentado

4.2

Para comprobar la compatibilidad de características entre versiones de un nodo, conéctese al nodo y ejecute el siguiente comando:

db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

Para obtener más información, consulte la página de referencia setFeatureCompatibilityVersion.

Transacciones son compatibles en conjuntos de réplicas y clústeres fragmentados donde:

  • el primario utiliza el motor de almacenamiento WiredTiger, y

  • los miembros secundarios utilizan el motor de almacenamiento WiredTiger o los motores de almacenamiento en memoria.

Nota

No puedes ejecutar transacciones en un clúster que tiene una partición con writeConcernMajorityJournalDefault configurada en false, como una partición con un nodo votante que utiliza el motor de almacenamiento en memoria.

A partir de MongoDB 5.2 (y 5.0.4):

  • Cuando una query accede a un fragmento, una migración de fragmento o una operación DDL puede retener la sección crítica de la colección.

  • Para limitar el tiempo que un fragmento espera por una sección crítica dentro de una transacción, utilice el parámetro metadataRefreshInTransactionMaxWaitMS.

    Nota

    A partir de MongoDB 8.1, el parámetro antiguo metadataRefreshInTransactionMaxWaitBehindCritSecMS se renombra a metadataRefreshInTransactionMaxWaitMS. Puedes continuar usando metadataRefreshInTransactionMaxWaitBehindCritSecMS como nombre de parámetro, pero está obsoleto y se eliminará en una versión futura de MongoDB.