Puede realizar una transacción para ejecutar una serie de operaciones que no modifican ningún dato hasta que se confirme toda la transacción. Este ejemplo de uso utiliza la API de transacciones convenientes para realizar una transacción.
Tip
Para obtener más información sobre la realización de transacciones en el controlador Node.js, consulte Guía de transacciones.
El controlador de Node.js también proporciona la API Core para realizar transacciones. Para obtener más información sobre la API Core, consulte el ejemplo de uso de la API Core.
Ejemplo
Imagine una situación en la que un cliente compra artículos en su tienda. Para registrar la compra, su aplicación debe actualizar el inventario y registrar la información del pedido.
La siguiente tabla describe las colecciones que almacenan datos de compra y cómo una compra cambia los datos en cada colección.
Colección | Operación | Descripción del cambio |
|---|---|---|
| insert | Inserta un documento que describe el pedido. |
| update | Actualiza las cantidades de artículos disponibles después de una compra. |
Datos de muestra
La colección inventory contiene los siguientes documentos:
{ item: "sunblock", qty: 85, price: 6.0 }, { item: "beach chair", qty: 30, price: 25.0 }
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.
Aplicación
El ejemplo de código de esta sección muestra cómo usar la API de Transacciones Convenientes para realizar una transacción multidocumento en una sesión. En este ejemplo, la transacción realiza los cambios necesarios cuando un cliente compra artículos en su tienda.
Este código de ejemplo realiza una transacción a través de las siguientes acciones:
Llama al método
withSession()en el cliente para crear implícitamente la sesión y ejecutar la devolución de llamada que se le pasa dentro de la sesión.Llama al método
withTransaction()en la sesión para crear una transacción, ejecutar la devolución de llamada que se le pasa y confirmarla. Si la transacción falla, este método la finaliza y devuelve un mensaje de error.Realiza las siguientes operaciones dentro de la transacción:
Actualiza las colecciones
inventoryyorderssi hay suficiente inventario para cumplir con la compraFinaliza la transacción y lanza una excepción si no hay suficiente inventario para algún artículo en el pedido
Devuelve un mensaje que reconoce que la transacción se realizó correctamente con una copia del registro de compra.
Imprime el tipo de retorno de
withSession(), que es el mensaje de error o el reconocimiento de que la transacción se completó.
const txnResult = await client.withSession(async (session) => session .withTransaction(async (session) => { const invColl = client.db("testdb").collection("inventory"); const recColl = client.db("testdb").collection("orders"); let total = 0; 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 invColl.findOneAndUpdate( { item: item.item, qty: { $gte: item.qty }, }, { $inc: { qty: -item.qty } }, { session } ); if (inStock === null) { await session.abortTransaction(); return "Item not found or insufficient quantity."; } const subTotal = item.qty * inStock.price; total = total + subTotal; } // Create a record of the purchase const receipt = { date: new Date(), items: order, total: total, }; await recColl.insertOne(receipt, { session }); return ( "Order successfully completed and recorded!\nReceipt:\n" + JSON.stringify(receipt, null, 1) ); }, null) .finally(async () => await client.close()) ); console.log(txnResult);
Órdenes de muestra y resultados de transacciones
En esta sección se describen los resultados de las transacciones realizadas para dos pedidos de muestra.
Existe suficiente inventario para el siguiente pedido, por lo que la transacción se completa exitosamente:
{ item: "sunblock", qty: 3 }, { item: "beach chair", qty: 1 }
Después de pasar esta orden al código de transacción de ejemplo, el código genera el siguiente resultado:
Order successfully completed and recorded! Receipt: { "date": "2023-08-25T20:06:52.564Z", "items": [ { "item": "sunblock", "qty": 3 }, { "item": "beach chair", "qty": 1 } ], "total": 43, "_id": "..." }
En la colección inventory, la cantidad de "sunblock" es ahora 82 y la cantidad de "beach chair" es 29. La colección orders contiene el registro de la compra.
No hay suficiente inventario para el siguiente pedido, por lo que el conductor finaliza la transacción:
{ item: "volleyball", qty: 1 }
Después de pasar esta orden al código de transacción de ejemplo, el código genera el siguiente resultado:
Item not found or insufficient quantity.
Una vez que el conductor finaliza la transacción, no hay cambios en las colecciones inventory y orders.
Documentación de la API
Para obtener más información sobre cualquiera de los métodos o tipos analizados en este ejemplo de uso, consulte la siguiente documentación de API: