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.
Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
MongoDB Branding Shape
Click here >
Docs Menu

Transacciones

En esta guía, puede aprender a utilizar el controlador C para realizar transacciones. Las transacciones te permiten realizar una serie de operaciones que cambian los datos solo si toda la transacción se completa. Si alguna operación en la transacción no tiene éxito, la librería detiene la transacción y descarta todos los cambios de datos antes de que se hagan visibles. Esta funcionalidad se llama atomicidad.

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

Cuando utilizas el driver de C, puedes crear una nueva sesión desde una instancia de mongoc_client_t. Luego, puedes utilizar la instancia resultante de mongoc_client_session_t para realizar transacciones.

Advertencia

Utiliza un mongoc_client_session_t solo con el mongoc_client_t (o el mongoc_database_t o mongoc_collection_t asociados) que lo creaste. El uso de un mongoc_client_session_t con un mongoc_client_t diferente resulta en errores de operación.

MongoDB habilita la coherencia causal en ciertas sesiones de clientes. El modelo de coherencia causal garantiza que en un sistema distribuido, las operaciones dentro de una sesión se ejecuten en un orden causal. Los clientes observan resultados que son coherentes con las relaciones causales, o las dependencias entre las operaciones. Por ejemplo, si realizas una serie de operaciones donde una depende lógicamente del resultado de otra, las lecturas subsecuentes reflejarán esa relación de dependencia.

Para garantizar la coherencia causal, las sesiones de los clientes deben cumplir los siguientes requisitos:

  • Al iniciar una sesión, el driver debe habilitar la opción de coherencia causal. Esta opción está habilitada por defecto.

  • Las operaciones deben ejecutarse en una sola sesión en un solo hilo. De lo contrario, las sesiones o hilos deben comunicarse entre sí los valores de operation time y tiempo de clúster. Para ver un ejemplo de dos sesiones que comunican estos valores, consulte los Ejemplos de coherencia causal en el manual del servidor de MongoDB.

  • Debes usar un MONGOC_READ_CONCERN_LEVEL_MAJORITY nivel de consistencia de lectura.

  • Debe usar un MONGOC_WRITE_CONCERN_W_MAJORITY nivel de confirmación de escritura (write concern). Este es el valor predeterminado de nivel de confirmación de escritura (write concern).

La siguiente tabla describe las garantías que ofrecen las sesiones coherentes causales:

garantías
Descripción

Leer las escrituras

Las operaciones de lectura reflejan los resultados de las operaciones de escritura anteriores.

Lecturas monotónicas

Las operaciones de lectura no devuelven resultados que reflejen un estado de datos anterior al de una operación de lectura previa.

Escrituras monotónicas

Si una operación de escritura debe preceder a otras operaciones de escritura, el servidor ejecutará primero esta operación de escritura.

Por ejemplo, si llamas a mongoc_collection_insert_one() para insertar un documento y luego llamas a mongoc_collection_update_one() para modificar el documento insertado, el servidor ejecutará primero la operación de inserción.

Las escrituras siguen a las lecturas

Si una operación de escritura debe seguir a otras operaciones de lectura, el servidor primero ejecuta las operaciones de lectura.

Por ejemplo, si llamas a mongoc_collection_find_with_opts() para recuperar un documento y luego llamas a mongoc_collection_delete_one() para borrar el documento recuperado, el servidor ejecutará primero la operación find.

Tip

Para aprender más sobre los conceptos mencionados en esta sección, consulta las siguientes entradas del manual del servidor MongoDB:

En esta sección, puede aprender sobre las APIs de transacciones proporcionadas por el controlador C. Antes de iniciar una transacción, debes crear un mongoc_client_session_t utilizando la función mongoc_client_start_session() en tu instancia mongoc_client_t. Luego, puede utilizar cualquiera de las siguientes API para realizar una transacción:

El controlador C proporciona una API de transacciones conveniente para gestionar el ciclo de vida de las transacciones. Implemente esta API usando la función mongoc_client_session_with_transaction() para ejecutar devoluciones de llamada personalizadas dentro de una transacción. La función mongoc_client_session_with_transaction() realiza las siguientes tareas:

  • Inicia la transacción

  • Gestiona los errores mediante la finalización de la transacción o su reintento, como cuando la operación da como resultado un TransientTransactionError

  • Confirma la transacción

La sección Ejemplo de Transacción de esta guía muestra cómo utilizar esta API para realizar una transacción.

Alternativamente, puedes tener más control sobre tu ciclo de vida de la transacción utilizando las siguientes funciones con tu instancia mongoc_client_session_t:

Función
Descripción

mongoc_client_session_start_transaction()

Inicia una nueva transacción, configurada con las opciones especificadas, en esta sesión. Devuelve false y establece el error proporcionado si hay argumentos no válidos, como una sesión con una transacción ya en curso. Para obtener más información sobre esta función, consulte la página startTransaction() en el manual del servidor.

mongoc_client_session_abort_transaction()

Finaliza la transacción activa de esta sesión. Devuelve false y establece el error proporcionado si no hay ninguna transacción activa en la sesión o si la transacción se ha confirmado o finalizado. Para obtener más información sobre esta función, consulte la página abortTransaction() en el manual del servidor.

mongoc_client_session_commit_transaction()

Confirma la transacción activa de esta sesión. Devuelve un error si no hay ninguna transacción activa o si la transacción ha finalizado. Para obtener más información sobre esta función, consulte la página commitTransaction() en el manual del servidor.

mongoc_client_session_destroy()

Cancela cualquier transacción en curso y finaliza esta sesión. Libera todos los recursos del cliente asociados a esta sesión.

Para aprender más información sobre funciones que recuperan propiedades de mongoc_client_session_t y modifican propiedades de sesión mutables, consulte la documentación de la API.

Este ejemplo define una función de retorno que modifica los datos en las colecciones de la base de datos sample_bank para una transacción bancaria. El código realiza las siguientes acciones:

  1. Define la función de retorno, que recibe la instancia mongoc_client_session_t como parámetro.

  2. Crea mongoc_collection_t instancias para acceder a las colecciones de destino.

  3. Especifica el número de cuenta y el monto que se transferirá entre cuentas.

  4. Actualiza los saldos del cliente para reflejar la transferencia de dinero.

  5. Registra un recibo de la transacción con una marca de tiempo.

  6. Imprime un mensaje si la transacción se comprometió correctamente.

bool
transaction_callback(mongoc_client_session_t *session, void *ctx, bson_t **reply,
bson_error_t *error)
{
BSON_UNUSED(ctx);
BSON_UNUSED(reply);
mongoc_client_t *client = mongoc_client_session_get_client(session);
mongoc_collection_t *checking = mongoc_client_get_collection(client, "sample_bank", "checking");
mongoc_collection_t *savings = mongoc_client_get_collection(client, "sample_bank", "savings");
mongoc_collection_t *receipts = mongoc_client_get_collection(client, "sample_bank", "receipts");
const char *account_id = "123456";
int transfer_amount = 1000;
bson_t *filter = BCON_NEW("account_id", BCON_UTF8(account_id));
bson_t *update_decrement = BCON_NEW("$inc", "{", "balance", BCON_INT32(-transfer_amount), "}");
bson_t *update_increment = BCON_NEW("$inc", "{", "balance", BCON_INT32(transfer_amount), "}");
bson_t *opts = bson_new();
BSON_ASSERT(mongoc_client_session_append(session, opts, error));
if (!mongoc_collection_update_one(checking, filter, update_decrement, opts, NULL, error)) {
fprintf(stderr, "Failed to update checking account: %s\n", error->message);
bson_destroy(opts);
return false;
}
if (!mongoc_collection_update_one(savings, filter, update_increment, opts, NULL, error)) {
fprintf(stderr, "Failed to update savings account: %s\n", error->message);
bson_destroy(opts);
return false;
}
bson_t *receipt = BCON_NEW("account_id", BCON_UTF8(account_id),
"amount", BCON_INT32(transfer_amount),
"timestamp", BCON_DATE_TIME(bson_get_monotonic_time()));
if (!mongoc_collection_insert_one(receipts, receipt, opts, NULL, error)) {
fprintf(stderr, "Failed to insert receipt: %s\n", error->message);
bson_destroy(opts);
return false;
}
bson_destroy(opts);
mongoc_collection_destroy(checking);
mongoc_collection_destroy(savings);
mongoc_collection_destroy(receipts);
bson_destroy(filter);
bson_destroy(update_decrement);
bson_destroy(update_increment);
bson_destroy(receipt);
printf("Transaction successful!");
return true;
}

A continuación, ejecuta el siguiente código para realizar la transacción. Este código completa las siguientes acciones:

  1. Crea una sesión desde el cliente usando la función mongoc_client_start_session().

  2. Llama a la función mongoc_client_session_with_transaction() para gestionar la transacción, pasando como parámetros la sesión y la función de retorno.

mongoc_client_session_t *session = mongoc_client_start_session(client, NULL, NULL);
if (!session) {
fprintf(stderr, "Failed to start session\n");
mongoc_client_destroy(client);
return EXIT_FAILURE;
}
bool result =
mongoc_client_session_with_transaction(session,
(mongoc_client_session_with_transaction_cb_t) transaction_callback,
NULL, NULL, NULL, &error);
if (!result) {
fprintf(stderr, "Transaction error: %s\n", error.message);
}
mongoc_client_session_destroy(session);
mongoc_client_destroy(client);
mongoc_cleanup();
Transaction successful!

Nota

Operaciones paralelas no admitidas

El driver de C no admite ejecutar operaciones paralelas dentro de una sola transacción.

Si utilizas MongoDB Server v8.0 o posterior, puedes realizar operaciones de escritura en múltiples espacios de nombres dentro de una única transacción mediante operaciones de escritura en lote. Para obtener más información, consulta la guía Operaciones masivas de guardar.

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

Para aprender más sobre ACID compliance, consulte el ¿Cuáles son las propiedades ACID en los sistemas de gestión de bases de datos? artículo en el sitio web de MongoDB.

Para obtener más información sobre cualquiera de los tipos o funciones que se tratan en esta guía, consulta la siguiente documentación de la API: