Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 40d6dd7

Browse files
committed
Add transactions inventory example
1 parent 6cc0b98 commit 40d6dd7

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

‎transaction-inventoryexample.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
const { MongoClient } = require('mongodb');
2+
3+
// In MongoDB 4.2 and earlier, CRUD operations in transactions must be on existing collections
4+
// See https://docs.mongodb.com/manual/core/transactions/#transactions-api for more information
5+
6+
// Before running this script...
7+
// 1. Create a database named 'book-store'
8+
// 2. Create a collection named 'orders' in the database
9+
// 3. Create a collection named 'inventory' in the database
10+
// 3. Create a document in the 'inventory' collection:
11+
// { "_id": "parks-rec-book", "name": "The Ultimate Parks and Rec Book for the Ultimate Fans", "numberInStock": 5 }
12+
// 4: Optional: Add schema validation to the 'inventory' collection to ensure the number of items in stock cannot drop below 0.
13+
// See https://docs.mongodb.com/manual/core/schema-validation/ for details on how to
14+
// enable schema validation. Configuring schema validation in MongoDB Compass is an
15+
// easy way to add schema validation to an existing database: https://docs.mongodb.com/compass/current/validation/
16+
//
17+
// {
18+
// $jsonSchema: {
19+
// properties: {
20+
// numberInStock: {
21+
// minimum: 0,
22+
// description: 'numberInStock cannot be negative'
23+
// }
24+
// }
25+
// }
26+
// }
27+
28+
async function main() {
29+
/**
30+
* Connection URI. Update <username>, <password>, and <your-cluster-url> to reflect your cluster.
31+
* See https://docs.mongodb.com/drivers/node/ for more details
32+
*/
33+
const uri = "mongodb+srv://<username>:<password>@<your-cluster-url>/book-store?retryWrites=true&w=majority";
34+
35+
/**
36+
* The Mongo Client you will use to interact with your database
37+
* See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html for more details
38+
*/
39+
const client = new MongoClient(uri);
40+
41+
try {
42+
// Connect to the MongoDB cluster
43+
await client.connect();
44+
45+
// User1 purchases 1 copy of parks-rec-book
46+
await purchaseBook(client, "User1", "parks-rec-book", 1, "paid");
47+
48+
} finally {
49+
// Close the connection to the MongoDB cluster
50+
await client.close();
51+
}
52+
}
53+
54+
main().catch(console.error);
55+
56+
/**
57+
* Purchase a book
58+
* @param {MongoClient} client A MongoClient that is connected to a cluster with the book-store database
59+
* @param {String} userId The _id of the user who is purchasing the book
60+
* @param {String} bookId The _id of the book being purchased
61+
* @param {Number} quantity The number of copies being purchased
62+
* @param {String} status The order status
63+
*/
64+
async function purchaseBook(client, userId, bookId, quantity, status) {
65+
66+
/**
67+
* The orders collection in the book-store database
68+
*/
69+
const ordersCollection = client.db("book-store").collection("orders");
70+
71+
/**
72+
* The inventory collection in the book-store database
73+
*/
74+
const inventoryCollection = client.db("book-store").collection("inventory");
75+
76+
// Step 1: Start a Client Session
77+
// See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html#startSession for the startSession() docs
78+
const session = client.startSession();
79+
80+
// Step 2: Optional. Define options for the transaction
81+
const transactionOptions = {
82+
readPreference: 'primary',
83+
readConcern: { level: 'local' },
84+
writeConcern: { w: 'majority' }
85+
};
86+
87+
try {
88+
// Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error)
89+
// Note: The callback for withTransaction MUST be async and/or return a Promise.
90+
// See https://mongodb.github.io/node-mongodb-native/3.6/api/ClientSession.html#withTransaction for the withTransaction() docs
91+
const transactionResults = await session.withTransaction(async () => {
92+
93+
// Important:: You must pass the session to each of the operations
94+
95+
// Update the inventory to reflect the book has been sold
96+
const updateInventoryResults = await inventoryCollection.updateOne(
97+
{ _id: bookId },
98+
{ $inc: { numberInStock: quantity * -1 } },
99+
{ session });
100+
console.log(`${updateInventoryResults.matchedCount} document(s) found in the inventory collection with _id ${bookId}.`);
101+
console.log(`${updateInventoryResults.modifiedCount} document(s) was/were updated.`);
102+
if (updateInventoryResults.modifiedCount !== 1) {
103+
await session.abortTransaction();
104+
return;
105+
}
106+
107+
// Record the order in the orders collection
108+
const insertOrderResults = await ordersCollection.insertOne(
109+
{ "userId": userId , bookId: bookId, quantity: quantity, status: status },
110+
{ session });
111+
console.log(`New order recorded with the following id: ${insertOrderResults.insertedId}`);
112+
113+
}, transactionOptions);
114+
115+
if (transactionResults) {
116+
console.log("The order was successfully processed. Database operations from the transaction are now visible outside the transaction.");
117+
} else {
118+
console.log("The order was not successful. The transaction was intentionally aborted.");
119+
}
120+
} catch (e) {
121+
console.log("The order was not successful. The transaction was aborted due to an unexpected error: " + e);
122+
} finally {
123+
// Step 4: End the session
124+
await session.endSession();
125+
}
126+
127+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /