Docs 菜单
Docs 主页
/ /

使用便捷事务 API

您可以执行一个事务来运行一系列操作,这些操作在提交整个事务之前不会更改任何数据。 此用法示例使用便捷事务 API来执行事务。

提示

要学习有关在 Node.js驱动程序中执行事务的更多信息,请参阅 事务指南。

Node.js 驱动程序还提供用于执行事务的 Core API。 要了解有关 Core API 的更多信息,请参阅使用 Core API用法示例。

考虑客户从您的商店购买商品的情况。 要记录购买,应用程序必须更新库存并记录订单信息。

下表描述了存储购买数据的collection,以及购买如何更改每个collection中的数据。

Collection
操作
变更说明

orders

insert

插入描述订单的文档

inventory

update

更新购买后可用商品的数量

inventory 集合包含以下文档:

{ item: "sunblock", qty: 85, price: 6.0 },
{ item: "beach chair", qty: 30, price: 25.0 }

您将购买记录存储在testdb数据库的orders集合中。 此collection为空,因为没有任何购买操作。

本节中的代码示例演示了如何使用便捷事务 API 在会话中执行多文档事务。 在此示例中,事务在客户从您的商店购买商品时进行所需的更改。

此示例代码通过以下动作执行事务:

  1. 在客户端上调用withSession()方法以隐式创建会话,并运行在会话中传递给它的回调。

  2. 为该会话调用 withTransaction() 方法来创建事务,运行传递给它的回调,然后提交事务。 如果事务失败,此方法会结束事务并返回错误消息。

  3. 在事务中执行以下操作:

    • 如果有足够的库存来完成采购,则更新inventoryorderscollection

    • 如果订单中的任何商品没有足够的库存,则结束事务并引发异常

    • 返回一条消息,确认已使用购买记录的副本成功提交事务

  4. 打印withSession()的返回类型,它可以是错误消息或事务完成的确认。

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);

本节描述了对两个样本订单执行的事务结果。

以下订单有足够的库存,因此事务成功完成:

{ item: "sunblock", qty: 3 },
{ item: "beach chair", qty: 1 }

将此订单传递给示例事务代码后,代码输出以下结果:

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": "..."
}

inventory集合中, "sunblock"的数量现在为82"beach chair"的数量为29orders collection 包含购买记录。

以下订单没有足够的库存,因此驱动程序结束事务:

{ item: "volleyball", qty: 1 }

将此订单传递给示例事务代码后,代码输出以下结果:

Item not found or insufficient quantity.

由于驱动程序结束事务,因此inventoryorders集合没有变化。

要了解有关此用法示例中讨论的任何方法或类型的更多信息,请参阅以下 API 文档:

  • withSession()

  • withTransaction()

  • abortTransaction()"

后退

事务

在此页面上