Definición
Session.commitTransaction()Guarda los cambios realizados por las operaciones en el transacción multi-documento y finaliza la transacción.
Importante
Método mongosh
Esta página documenta un método
mongosh. Esta no es la documentación para los comandos de base de datos ni para los drivers específicos de lenguajes, como Nodo.js.Para el comando de base de datos, consulta el comando
commitTransaction.Para los drivers de API de MongoDB, consulte la documentación del driver de MongoDB específica del lenguaje.
Cambiado en la versión 4.2: A partir de MongoDB 4.2, las transacciones multi-documento están disponibles tanto para clústeres particionados como para sets de réplicas.
Comportamiento
Nivel de confirmación de escritura
Al confirmar la transacción, la sesión utiliza el nivel de confirmación de escritura (write concern) especificado al inicio de la transacción. Consulta Session.startTransaction().
Si confirmas utilizando "w: 1" nivel de confirmación de escritura (write concern), tu transacción puede ser revertida durante el proceso de failover.
Atomicidad
Cuando se confirma una transacción, todos los cambios realizados en los datos se guardan y son visibles fuera de ella. Es decir, una transacción no confirmará algunos de sus cambios mientras revierte otros.
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.
Reintentar
Si la operación de confirmación encuentra un error, los controladores de MongoDB reintentan la operación de confirmación una sola vez sin importar si retryWrites está configurado en false. Para obtener más información, consulta Gestión de errores de transacciones.
Ejemplo
Imagine un escenario en el que, al realizar cambios en el registro de un empleado en la base de datos hr, desea asegurarse de que la colección events en la base de datos reporting esté sincronizada con los cambios hr. Es decir, desea asegurarse de que estas escrituras se realicen como una sola transacción, de modo que ambas operaciones se realicen correctamente o fallen.
La colección employees en la base de datos hr contiene los siguientes documentos:
{ "_id" : ObjectId("5af0776263426f87dd69319a"), "employee" : 3, "name" : { "title" : "Mr.", "name" : "Iba Ochs" }, "status" : "Active", "department" : "ABC" } { "_id" : ObjectId("5af0776263426f87dd693198"), "employee" : 1, "name" : { "title" : "Miss", "name" : "Ann Thrope" }, "status" : "Active", "department" : "ABC" } { "_id" : ObjectId("5af0776263426f87dd693199"), "employee" : 2, "name" : { "title" : "Mrs.", "name" : "Eppie Delta" }, "status" : "Active", "department" : "XYZ" }
La colección events en la base de datos reporting contiene los siguientes documentos:
{ "_id" : ObjectId("5af07daa051d92f02462644a"), "employee" : 1, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } } { "_id" : ObjectId("5af07daa051d92f02462644b"), "employee" : 2, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "XYZ", "old" : null } } { "_id" : ObjectId("5af07daa051d92f02462644c"), "employee" : 3, "status" : { "new" : "Active", "old" : null }, "department" : { "new" : "ABC", "old" : null } }
El siguiente ejemplo inicia una transacción, actualiza el estado de un empleado a Inactive en el estado employees e inserta un documento correspondiente en la colección events, así como confirma las dos operaciones como una única transacción.
// Runs the txnFunc and retries if TransientTransactionError encountered function runTransactionWithRetry(txnFunc, session) { while (true) { try { txnFunc(session); // performs transaction break; } catch (error) { // If transient error, retry the whole transaction if (error?.errorLabels?.includes("TransientTransactionError") ) { print("TransientTransactionError, retrying transaction ..."); continue; } else { throw error; } } } } // Retries commit if UnknownTransactionCommitResult encountered function commitWithRetry(session) { while (true) { try { session.commitTransaction(); // Uses write concern set at transaction start. print("Transaction committed."); break; } catch (error) { // Can retry commit if (error?.errorLabels?.includes("UnknownTransactionCommitResult") ) { print("UnknownTransactionCommitResult, retrying commit operation ..."); continue; } else { print("Error during commit ..."); throw error; } } } } // Updates two collections in a transactions function updateEmployeeInfo(session) { employeesCollection = session.getDatabase("hr").employees; eventsCollection = session.getDatabase("reporting").events; session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } ); try{ employeesCollection.updateOne( { employee: 3 }, { $set: { status: "Inactive" } } ); eventsCollection.insertOne( { employee: 3, status: { new: "Inactive", old: "Active" } } ); } catch (error) { print("Caught exception during transaction, aborting."); session.abortTransaction(); throw error; } commitWithRetry(session); } // Start a session. session = db.getMongo().startSession( { readPreference: { mode: "primary" } } ); try{ runTransactionWithRetry(updateEmployeeInfo, session); } catch (error) { // Do something with error } finally { session.endSession(); }