Transacciones

Transacciones multidocumento con aislamiento por instantánea entre rangos.

Las transacciones de MongoDB funcionan igual. Abres una sesión, haces varias operaciones y las confirmas o las anulas juntas. Las operaciones pueden tocar documentos de rangos y nodos distintos.

Requisitos

  • Una conexión con un usuario que tenga readWrite sobre las bases que toca la transacción.

Abrir una transacción

JavaScript
const session = db.getMongo().startSession();
session.withTransaction(() => {
  const cuentas = session.getDatabase("banco").cuentas;
  cuentas.updateOne({ _id: "A" }, { $inc: { saldo: -100 } });
  cuentas.updateOne({ _id: "B" }, { $inc: { saldo: 100 } });
});

Aislamiento

Cada transacción lee una instantánea a su marca de lectura y ve sus propias escrituras. Dentro de una transacción, readConcern local, majority y snapshot leen los tres esa misma instantánea.

Cómo confirma

Si todas las claves de la transacción están en un rango, se confirma en una fase. Si no, cada rango guarda versiones provisionales y un registro de transacción decide; la limpieza de esas versiones sigue en segundo plano después de responder.

Límites y errores

Las etiquetas de error (TransientTransactionError, UnknownTransactionCommitResult) y el reintento del commit son los de MongoDB, así que withTransaction de los drivers reintenta lo que debe. transactionLifetimeLimitSeconds vale 60 por defecto y se cambia con setParameter.

Consistencia causal

Las sesiones de los drivers con causalConsistency funcionan: una lectura con afterClusterTime ve todo lo que la sesión ya escribió o leyó, también si va a otra réplica.

Comprobar

Después del commit, una lectura de las dos cuentas ve los dos cambios; si la transacción se anula, no ve ninguno.

Problemas frecuentes

  • La transacción se anula al pasar de 60 segundos, el valor por defecto de transactionLifetimeLimitSeconds. Divídela o sube el límite con setParameter.
  • Una operación falla con TransientTransactionError. withTransaction la reintenta; si escribes el bucle a mano, reintenta tú la transacción entera.

Ver también