文档菜单
文档首页
/ / /
Node.js 驱动程序
/ /

使用便捷事务 API

本页内容

  • 示例
  • 示例数据
  • 实现
  • 示例订单和事务结果
  • API 文档

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

提示

另请参阅

要了解关于Node.js驱动程序中执行事务的更多信息,请参阅事务 指南。

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

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

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

集合
操作
变更描述
orders
insert
插入描述订单的文档
inventory
update
更新购买后可用的项目数量

inventory 集合包含以下文档

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

您将购买记录存储在 orders 集合中,该集合位于 testdb 数据库中。由于没有购买,此集合为空。

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

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

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

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

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

    • 如果库存充足以满足购买,则更新 inventoryorders 集合

    • 如果订单中任何商品的库存不足,则结束事务并抛出异常

    • 返回消息确认事务成功提交,并提供购买记录的副本

  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" 的数量是 29。在 orders 集合中包含购买记录。

以下订单的库存不足,因此驱动器结束事务

{ item: "volleyball", qty: 1 }

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

Item not found or insufficient quantity.

由于驱动器结束事务,对 inventoryorders 集合没有进行任何更改。

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

  • withSession()

  • withTransaction()

  • abortTransaction()"

返回

执行事务