Docs Menu
Docs Home
/ /

Transacciones

En esta guía, aprenderá a usar el controlador C++ de MongoDB para realizar transacciones. Las transacciones permiten ejecutar una serie de operaciones que no modifican ningún dato hasta que se confirman. Si alguna operación de la transacción devuelve un error, el controlador la cancela y descarta todos los cambios en los datos antes de que sean visibles.

En MongoDB, las transacciones se ejecutan dentro de sesiones lógicas. Una sesión es un grupo de operaciones de lectura o escritura relacionadas que tienes la intención de ejecutar secuencialmente. Las sesiones permiten la coherencia causal para un grupo de operaciones en una transacción compatible con ACID, que es una transacción que cumple con la expectativa de atomicidad, coherencia, aislamiento y durabilidad. MongoDB garantiza que los datos involucrados en sus operaciones de transacción permanecen coherentes, incluso si las operaciones encuentran errores inesperados.

Al utilizar el controlador C++, puede crear una nueva sesión desde un mongocxx::client Instancia. Luego, puede usar la instancia mongocxx::client_session resultante para realizar transacciones. Le recomendamos reutilizar su cliente para múltiples sesiones y transacciones en lugar de instanciar un nuevo cliente cada vez.

Advertencia

Use un mongocxx::client_session solo con el mongocxx::client que lo creó. Usar un client_session con un client diferente genera errores de operación.

Importante

Las instancias de mongocxx::client no son seguras para subprocesos. Cada instancia de mongoxcc::client y sus instancias secundarias, incluyendo mongocxx::client_session, deben ser utilizadas por un solo subproceso a la vez. Para obtener más información, consulte Guía deseguridad de roscas y horquillas.

El controlador C++ de MongoDB proporciona una API de devolución de llamada y una API principal para gestionar el estilo de vida de las transacciones. Antes de iniciar una transacción, debe llamar al método start_session() para instanciar un mongocxx::client_session. A continuación, puede usar cualquiera de las siguientes API para realizar una transacción:

  • API de devolución de llamada: API de alto nivel que administra el ciclo de vida de la transacción e incorpora automáticamente lógica de manejo de errores.

  • API principal: API de bajo nivel que le permite administrar el ciclo de vida de la transacción e implementar una lógica de manejo de errores personalizada.

Tip

Para obtener más información sobre el manejo de errores, consulte la sección Manejo de errores de transacciones en el manual de MongoDB Server.

Utilice la API de devolución de llamada para que el controlador C++ de MongoDB gestione el ciclo de vida de su transacción. Para implementar esta API, llame al método with_transaction() en su mongocxx::client_session y pase una función de devolución de llamada que especifique la secuencia de operaciones que desea ejecutar. El método with_transaction() inicia una transacción, ejecuta la función de devolución de llamada y confirma o finaliza la transacción si encuentra un error. Si su transacción encuentra un error TransientTransactionError o UnknownTransactionCommitResult, el método with_transaction() la vuelve a ejecutar.

El siguiente código utiliza la API de callback para realizar una transacción que inserta documentos en las colecciones movies y comments en la base de datos sample_mflix. Este código realiza las siguientes acciones:

  1. Inicia una sesión desde el cliente utilizando el método start_session().

  2. Define una función de devolución de llamada que especifica las operaciones a realizar durante la transacción.

  3. Crea un objeto de opción para preparar la configuración de la preocupación de escritura para las operaciones de transacción. Para obtener más información sobre la semántica de lectura y escritura, consulte la sección "Preferencia de lectura/Preferencia de escritura/Preferencia de lectura" del manual de MongoDB Server.

  4. Llama al método with_transaction() para administrar la transacción, pasando la función de devolución de llamada y el objeto de opción como argumentos.

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define a callback specifying the sequence of operations to perform during the transaction
mongocxx::client_session::with_transaction_cb callback = [&](mongocxx::client_session* session) {
// Important:: You must pass the session to the operations.
movies_collection.insert_one(*session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(*session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
};
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
// Start a client session
auto session = client.start_session();
try {
// Start a transaction, execute the operations in the callback function, and commit the results
session.with_transaction(callback, opts);
} catch (const mongocxx::exception& e) {
std::cout << "An exception occurred: " << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;

Utilice la API principal para gestionar el ciclo de vida de sus transacciones. Para implementar esta API, debe realizar llamadas explícitas a los métodos de la interfaz mongocxx::client_session para iniciar una transacción, confirmar una transacción activa y finalizarla si se produce un error. La API principal no incorpora automáticamente la lógica de gestión de errores, sino que permite implementar una lógica de gestión personalizada para errores como TransientTransactionError y UnknownTransactionCommitResult.

La siguiente tabla describe los métodos API principales proporcionados por la interfaz mongocxx::client_session:

Método
Descripción

start_transaction()

Starts a new transaction on the current client session. Accepts an optional mongocxx::options::transaction instance as an argument to set options. For a full list of options, see mongocxx::options::transaction in the API documentation.

Raises an exception if the options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with a transaction already in progress. If an error is returned with the TransientTransactionError label, you can end the transaction and then retry it with the expectation that it will succeed.

To learn more about this method, see the startTransaction() guide in the MongoDB Server manual.

commit_transaction()

Commits the active transaction on the current client session.

Raises an exception if options are misconfigured, if there are network or other transient failures, or if there are other errors such as a session with no transaction in progress. If an error is returned with the UnknownTransactionCommitResult label, you can end the transaction and then retry it with the expectation that it will succeed when the committed transaction satisfies the set write concern.

To learn more about this method, see the commitTransaction() guide in the MongoDB Server manual.

abort_transaction()

Ends the active transaction on the current client session.

Raises an exception if the options are misconfigured or if there are other errors such as a session with no transaction in progress.

To learn more about this method, see the abortTransaction() guide in the MongoDB Server manual.

Tip

La mongocxx::client_session clase también proporciona métodos para recuperar y modificar las propiedades de la sesión. Para obtener más información, consulte mongocxx::client_session en la documentación de la API.

El siguiente código utiliza la API principal para realizar una transacción que inserta documentos en las colecciones movies y comments de la base de datos sample_mflix. Este código realiza las siguientes acciones:

  1. Inicia una sesión desde el cliente utilizando el método start_session().

  2. Crea un objeto de opción para preparar la configuración de la preocupación de escritura para las operaciones de transacción. Para obtener más información sobre la semántica de lectura y escritura, consulte la sección "Preferencia de lectura/Preferencia de escritura/Preferencia de lectura" del manual de MongoDB Server.

  3. Llama al método start_transaction() para iniciar una transacción, pasando el objeto de opción como argumento.

  4. Ejecuta operaciones para insertar documentos en colecciones de la base de datos sample_mflix, pasando la sesión activa a cada operación. Si una operación detecta un error, se cancela toda la transacción. Si el error tiene la etiqueta TransientTransactionError, se reintenta la transacción.

  5. Confirma la transacción activa utilizando el método commit_transaction(). Si la confirmación encuentra un error con la etiqueta UnknownTransactionCommitResult, se volverá a intentar la confirmación.

// Establish a connection to the MongoDB deployment
mongocxx::instance instance{};
mongocxx::client client(mongocxx::uri{"<connectionString>"});
// Runs the txn_func and retries if TransientTransactionError occurs
using transaction_func = std::function<void(mongocxx::client_session& session)>;
auto run_with_retry = [](transaction_func txn_func,
mongocxx::client_session& session) {
while (true) {
try {
txn_func(session); // performs transaction.
break;
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Transaction aborted. Caught exception during transaction."
<< std::endl;
// If transient error, retry the whole transaction.
if (oe.has_error_label("TransientTransactionError")) {
std::cout << "TransientTransactionError, retrying transaction..."
<< std::endl;
continue;
} else {
throw oe;
}
}
}
};
// Commits the active transaction and retries commit if UnknownTransactionCommitResult occurs
auto commit_with_retry = [](mongocxx::client_session& session) {
while (true) {
try {
session.commit_transaction(); // Uses write concern set at transaction start.
std::cout << "Transaction committed."
<< std::endl;
break;
} catch (const mongocxx::operation_exception& oe) {
// Can retry commit
if (oe.has_error_label("UnknownTransactionCommitResult")) {
std::cout << "UnknownTransactionCommitResult, retrying commit..."
<< std::endl;
continue;
} else {
std::cout << "Error during commit..."
<< std::endl;
throw oe;
}
}
}
};
auto txn_func = [&](mongocxx::client_session& session) {
auto& client = session.client();
// Define database and collection variables
auto db = client["sample_mflix"];
auto movies_collection = db["movies"];
auto comments_collection = db["comments"];
// Define an options instance to explicitly set the write concern for the transaction operations
mongocxx::options::transaction opts;
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_majority);
opts.write_concern(wc);
session.start_transaction(opts);
// Attempt to insert documents into database collections
try {
movies_collection.insert_one(session, make_document(kvp("title", "Parasite")));
comments_collection.insert_one(session, make_document(kvp("name", "Anjali Patel"),
kvp("text", "This is my new favorite movie!")));
} catch (const mongocxx::operation_exception& oe) {
std::cout << "Caught exception during transaction, aborting."
<< std::endl;
session.abort_transaction();
throw oe;
}
commit_with_retry(session);
};
// Start a client session
auto session = client.start_session();
try {
run_with_retry(txn_func, session);
} catch (const mongocxx::operation_exception& oe) {
// Do something with error
throw oe;
}

Para obtener más información sobre los conceptos analizados en esta guía, consulte las siguientes páginas del manual de MongoDB Server:

Para obtener más información sobre la compatibilidad de ACID, consulte la guía Propiedades ACID en sistemas de administración de bases de datos en el sitio web de MongoDB.

Para obtener más información sobre las operaciones de inserción, consulte la guía Insertar documentos.

Para obtener más información sobre cualquiera de los tipos o métodos analizados en esta guía, consulte la siguiente documentación de API:

Volver

GridFS

En esta página