Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Utilice la API principal

Puede ejecutar una transacción para ejecutar una serie de operaciones que no cambian los datos hasta que se confirme completamente la transacción. Este ejemplo de uso utiliza la Core API para realizar una transacción.

Tip

Para obtener más información sobre la realización de transacciones en el controlador Node.js, consulte Transactions guide.

El controlador de Node.js también proporciona la API de Transacciones Convenientes para realizar transacciones. Para obtener más información sobre la API de transacciones conveniente, consulta el ejemplo de uso de Usa la API de transacciones conveniente.

Considera una situación en la que un cliente compra artículos en tu tienda en linea. Para registrar la compra, tu aplicación debe actualizar tu inventario y los pedidos de los clientes. Tu aplicación también debe guardar los detalles del pedido.

La siguiente tabla describe las colecciones que almacenan datos de compra y cómo una compra modifica los datos en cada colección.

Colección
Operación
Descripción del cambio

orders

insert

Inserta un documento que describe el pedido.

customers

actualizar o inserción

Añade el _id del documento de pedido al historial de pedidos en el documento del cliente

inventory

update

Actualiza las cantidades de artículos disponibles después de una compra.

Los ejemplos de código usan los siguientes datos de muestra en la base de datos testdb:

  • Documentos de la colección customers que describen a los clientes y sus pedidos anteriores

  • Documentos en la colección inventory que incluyen cantidades y descripciones de todos los artículos

El siguiente documento está en la colección customers:

{ _id: 98765, orders: [] }

La colección inventory contiene los siguientes documentos:

{ item: "sunblock", item_id: 5432, qty: 85 },
{ item: "beach towel", item_id: 7865, qty: 41 }

Almacena los registros de compra en la colección orders de la base de datos testdb. Esta colección está vacía, ya que no se han realizado compras.

Los ejemplos de código utilizan las variables cart y payment para representar una lista de muestra de artículos comprados y los detalles de pago del pedido. El código siguiente describe el contenido de las variables cart y payment:

const cart = [
{ item: 'sunblock', item_id: 5432, qty: 1, price: 5.19 },
{ item: 'beach towel', item_id: 7865, qty: 2, price: 15.99 }
];
const payment = { customer: 98765, total: 37.17 };

El ejemplo de código en esta sección demuestra cómo utilizar la Core API para realizar una transacción con múltiples documentos en una sesión. En este ejemplo, la transacción realiza los cambios necesarios cuando un cliente adquiere artículos en tu tienda.

Este código de ejemplo realiza una transacción mediante las siguientes acciones:

  1. Llama al método startSession() para crear una nueva sesión

  2. Llama al método startTransaction() con un parámetro de opciones para crear una nueva transacción

  3. Realiza las siguientes operaciones dentro de la transacción:

    • Inserta un documento en la colección orders que contiene información sobre la compra y el cliente

    • Actualiza la colección inventory si hay suficiente inventario para completar la compra

    • Termina la transacción y lanza una excepción si no hay suficiente inventario para algún artículo del pedido.

    • Agrega el ID del pedido a la lista de pedidos anteriores del cliente

    • Devuelve un mensaje reconociendo que la transacción se completó correctamente con una copia del registro de compra

  4. Llama al método commitTransaction() para confirmar la transacción si todas las operaciones se completan correctamente

  5. Implementa un bloque catch que contiene lógica de manejo de errores

  6. Llama al método abortTransaction() para finalizar la transacción

  7. Llama al método endSession() para finalizar la sesión

async function placeOrder(client, cart, payment) {
const transactionOptions = {
readConcern: { level: 'snapshot' },
writeConcern: { w: 'majority' },
readPreference: 'primary'
};
// Start the session
const session = client.startSession();
try {
// Start the transaction in the session, specifying the transaction options
session.startTransaction(transactionOptions);
const ordersCollection = client.db('testdb').collection('orders');
/* Within the session, insert an order that contains information about the
customer, items purchased, and the total payment */
const orderResult = await ordersCollection.insertOne(
{
customer: payment.customer,
items: cart,
total: payment.total,
},
{ session }
);
const inventoryCollection = client.db('testdb').collection('inventory');
for (const item of order) {
/* Update the inventory for the purchased items. End the
transaction if the quantity of an item in the inventory is
insufficient to complete the purchase. */
const inStock = await inventoryCollection.findOneAndUpdate(
{
item_id: item.item_id,
item_id: { $gte: item.qty }
},
{ $inc: { 'qty': -item.qty }},
{ session }
)
if (inStock === null) {
throw new Error('Insufficient quantity or item ID not found.');
}
}
const customerCollection = client.db('testdb').collection('customers');
// Within the session, add the order details to the "orders" array of the customer document
await customerCollection.updateOne(
{ _id: payment.customer },
{ $push: { orders: orderResult.insertedId }},
{ session }
);
// Commit the transaction to apply all updates performed within it
await session.commitTransaction();
console.log('Transaction successfully committed.');
} catch (error) {
/*
Handle any exceptions thrown during the transaction and end the
transaction. Roll back all the updates performed in the transaction.
*/
if (error instanceof MongoError && error.hasErrorLabel('UnknownTransactionCommitResult')) {
// Add your logic to retry or handle the error
}
else if (error instanceof MongoError && error.hasErrorLabel('TransientTransactionError')) {
// Add your logic to retry or handle the error
} else {
console.log('An error occured in the transaction, performing a data rollback:' + error);
}
await session.abortTransaction();
} finally {
// End the session
await session.endSession();
}
}

Tip

Gestión explícita de recursos

El driver de Nodo.js admite nativamente la gestión explícita de recursos para MongoClient, ClientSession, ChangeStreams y cursores. Esta funcionalidad es experimental y está sujeta a cambios. Para aprender a usar la gestión explícita de recursos, consulta el Notas de versión v6.9.

Esta sección describe los cambios de datos creados por la transacción.

La colección customers contiene el documento del cliente con un pedido _id añadido al campo de pedidos:

{
"_id": 98765,
"orders": [
"61dc..."
]
}

La colección inventory contiene cantidades actualizadas para los artículos "sunblock" y "beach towel":

[
{
"_id": ...,
"item": "sunblock",
"item_id": 5432,
"qty": 84
},
{
"_id": ...,
"item": "beach towel",
"item_id": 7865,
"qty": 39
}
]

La colección orders contiene la información del pedido y el pago:

[
{
"_id": "...",
"customer": 98765,
"items": [
{
"item": "sunblock",
"item_id": 5432,
"qty": 1,
"price": 5.19
},
{
"item": "beach towel",
"item_id": 7865,
"qty": 2,
"price": 15.99
}
],
"total": 37.17
}
]

Para obtener más información sobre cualquiera de los métodos o tipos tratados en este ejemplo de uso, consulta la siguiente Documentación de la API:

Volver

API de transacciones convenientes

En esta página