Docs Menu
Docs Home
/ / /
Node.js ドライバー
/ /

Convenient Transaction API の使用

項目一覧

  • サンプル データ
  • 実装
  • サンプル注文とトランザクションの結果
  • API ドキュメント

トランザクションを実行して、トランザクション全体がコミットされるまでデータを変更しない一連の操作を実行できます。 この使用例では、 Convenient Transaction APIを使用してトランザクションを実行します。

Tip

以下も参照してください。

Node.js ドライバーでトランザクションを実行する方法の詳細については、 トランザクションガイドを参照してください。

Node.js ドライバーは、トランザクションを実行するための Core API も提供します。 Core API の詳細については、 「 Core APIの使用例 」を参照してください。

カスタマーが店舗から商品を購入するシナリオを考えてみましょう。 購入を記録するには、アプリケーションで在庫を更新し、注文情報を記録する必要があります。

次の表では、購入データを保存するコレクションと、購入によって各コレクションのデータがどのように変更されるかについて説明しています。

コレクション
操作
変更の説明
orders
insert
順序を説明するドキュメントを挿入します
inventory
update
購入後に利用可能なアイテムの量を更新します

inventory コレクションには次のドキュメントが含まれます。

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

購入レコードは、 testdbデータベースのordersコレクションに保存します。 購入がないため、このコレクションは空です。

このセクションのコード例は、 Convenient Transaction API を使用してセッション内でマルチドキュメントトランザクションを実行する方法を示しています。 この例では、トランザクションは、顧客が店舗から商品を購入する際に必要な変更を行っています。

このサンプル コードでは、次のアクションを通じてトランザクションを実行します。

  1. クライアントでwithSession()メソッドを呼び出して暗黙的にセッションを作成し、それに渡されたコールバックをセッション内で実行します。

  2. セッションでwithTransaction()メソッドを呼び出してトランザクションを作成し、それに渡されたコールバックを実行して、トランザクションをコミットします。 トランザクションが失敗した場合、このメソッドはトランザクションを終了し、エラーメッセージを返します。

  3. トランザクション内で次の操作を実行します。

    • 購入を実行するのに十分な在庫がある場合は、 inventoryコレクションとordersコレクションを更新します

    • トランザクションを終了し、注文内のどのアイテムの在庫が十分でない場合は例外をスローします

    • 購入レコードのコピーを使用して、トランザクションが正常にコミットされたことを確認するメッセージを返します

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

このセクションでは、2 つのサンプル注文に対して実行されたトランザクションの結果について説明します。

以下の注文向けの十分な在庫があるため、トランザクションは正常に完了します。

{ 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.

ドライバーがトランザクションを終了するため、inventory ordersコレクションと コレクションは変更されません。

この使用例で説明したメソッドやタイプの詳細については、次の API ドキュメントを参照してください。

  • withSession()

  • withTransaction()

  • abortTransaction()"

戻る

トランザクションの実行