使用便捷事务 API
您可以执行一个事务来运行一系列操作,这些操作在提交整个事务之前不会更改任何数据。 此用法示例使用便捷事务 API来执行事务。
提示
另请参阅:
要学习;了解有关在 Node.js驾驶员中执行事务的更多信息,请参阅事务指南。
Node.js 驱动程序还提供用于执行事务的 Core API。 要了解有关 Core API 的更多信息,请参阅使用 Core API用法示例。
例子
考虑客户从您的商店购买商品的情况。 要记录购买,应用程序必须更新库存并记录订单信息。
下表描述了存储购买数据的collection,以及购买如何更改每个collection中的数据。
Collection | 操作 | 变更说明 |
---|---|---|
| insert | 插入描述订单的文档 |
| update | 更新购买后可用商品的数量 |
样本数据
inventory
集合包含以下文档:
{ item: "sunblock", qty: 85, price: 6.0 }, { item: "beach chair", qty: 30, price: 25.0 }
您将购买记录存储在testdb
数据库的orders
集合中。 此collection为空,因为没有任何购买操作。
实现
本节中的代码示例演示了如何使用便捷事务 API 在会话中执行多文档事务。 在此示例中,事务在客户从您的商店购买商品时进行所需的更改。
此示例代码通过以下动作执行事务:
在客户端上调用
withSession()
方法以隐式创建会话,并运行在会话中传递给它的回调。为该会话调用
withTransaction()
方法来创建事务,运行传递给它的回调,然后提交事务。 如果事务失败,此方法会结束事务并返回错误消息。在事务中执行以下操作:
如果有足够的库存来完成采购,则更新
inventory
和orders
collection如果订单中的任何商品没有足够的库存,则结束事务并引发异常
返回一条消息,确认已使用购买记录的副本成功提交事务
打印
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
collection 包含购买记录。
以下订单没有足够的库存,因此驱动程序结束事务:
{ item: "volleyball", qty: 1 }
将此订单传递给示例事务代码后,代码输出以下结果:
Item not found or insufficient quantity.
由于驱动程序结束事务,因此inventory
和orders
集合没有变化。
API 文档
要了解有关此用法示例中讨论的任何方法或类型的更多信息,请参阅以下 API 文档: