Docs 菜单
Docs 主页
/ / /
Node.js 驱动程序
/ /

使用 Core API

在此页面上

  • 例子
  • 样本数据
  • 实现
  • 事务结果
  • API 文档

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

提示

另请参阅:

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

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

考虑客户从您的在线商店购买商品的情况。 要记录购买,应用程序必须更新库存和客户订单。 您的应用程序还需要保存订单详细信息。

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

Collection
操作
变更说明
orders
insert
插入描述订单的文档
customers
更新或更新插入
将订单文档中的_id附加到客户文档中的订单历史记录中
inventory
update
更新购买后可用商品的数量

代码示例使用testdb数据库中的以下样本数据:

  • customers 集合中描述客户及其过往订单的文档

  • inventorycollection中的文档,其中包括所有商品的数量和说明

以下文档位于customerscollection中:

{ _id: 98765, orders: [] }

inventory 集合包含以下文档:

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

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

代码示例使用cartpayment变量来表示所购商品的样本清单和订单付款详情。 以下代码描述了cartpayment变量的内容:

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

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

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

  1. 调用startSession()方法创建新会话

  2. 使用选项参数调用startTransaction()方法以创建新事务

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

    • 将文档插入到orders集合中,其中包含有关购买和客户的信息

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

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

    • 将订单 ID 添加到客户过去的订单列表中

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

  4. 如果所有操作均成功完成,则调用commitTransaction()方法提交事务

  5. 实现包含错误处理逻辑的catch区块

  6. 调用abortTransaction()方法结束事务

  7. 调用endSession()方法结束会话

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

本节描述事务创建的数据更改。

The customers collection 包含客户文档,其订单字段附加了订单_id

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

inventory集合包含"sunblock""beach towel"项的更新数量:

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

orders集合包含订单和付款信息:

[
{
"_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
}
]

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

  • transactionOptions

  • ClientSession

  • startSession()

  • startTransaction()

  • commitTransaction()

  • abortTransaction()

  • endSession()

后退

使用便捷事务 API