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 c745999

Browse files
committed
Add Transactions Banking Example
1 parent 87039b4 commit c745999

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

‎transaction-bankingexample.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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 'banking'
8+
// 2. Create a collection named 'accounts' in the database
9+
// 3. Create two documents in the 'accounts' collection:
10+
// {"_id":"account1", "balance":500}
11+
// {"_id":"account2", "balance":0}
12+
// 4: Optional: add schema validation to ensure an account balance 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+
// balance: {
21+
// minimum: 0,
22+
// description: 'account balance 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>/sample_airbnb?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+
// Transfer 100ドル from "account1" to "account2"
46+
await transferMoney(client, "account1", "account2", 100);
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+
* Transfer money from one bank account to another using
58+
* @param {MongoClient} client A MongoClient that is connected to a cluster with the banking database
59+
* @param {String} account1 The _id of the account where money should be subtracted
60+
* @param {String} account2 The _id of the account where money should be added
61+
* @param {Number} amount The amount of money to be transferred
62+
*/
63+
async function transferMoney(client, account1, account2, amount) {
64+
65+
/**
66+
* The accounts collection in the banking database
67+
*/
68+
const accountsCollection = client.db("banking").collection("accounts");
69+
70+
// Step 1: Start a Client Session
71+
// See https://mongodb.github.io/node-mongodb-native/3.6/api/MongoClient.html#startSession for the startSession() docs
72+
const session = client.startSession();
73+
74+
// Step 2: Optional. Define options for the transaction
75+
const transactionOptions = {
76+
readPreference: 'primary',
77+
readConcern: { level: 'local' },
78+
writeConcern: { w: 'majority' }
79+
};
80+
81+
try {
82+
// Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error)
83+
// Note: The callback for withTransaction MUST be async and/or return a Promise.
84+
// See https://mongodb.github.io/node-mongodb-native/3.6/api/ClientSession.html#withTransaction for the withTransaction() docs
85+
const transactionResults = await session.withTransaction(async () => {
86+
87+
// Important:: You must pass the session to each of the operations
88+
89+
// Remove the money from the first account
90+
const subtractMoneyResults = await accountsCollection.updateOne(
91+
{ _id: account1 },
92+
{ $inc: { balance: amount * -1 } },
93+
{ session });
94+
console.log(`${subtractMoneyResults.matchedCount} document(s) found in the accounts collection with _id ${account1}.`);
95+
console.log(`${subtractMoneyResults.modifiedCount} document(s) was/were updated to remove the money.`);
96+
if (subtractMoneyResults.modifiedCount !== 1) {
97+
await session.abortTransaction();
98+
return;
99+
}
100+
101+
// Add the money to the second account
102+
const addMoneyResults = await accountsCollection.updateOne(
103+
{ _id: account2 },
104+
{ $inc: { balance: amount } },
105+
{ session });
106+
console.log(`${addMoneyResults.matchedCount} document(s) found in the accounts collection with _id ${account2}.`);
107+
console.log(`${addMoneyResults.modifiedCount} document(s) was/were updated to add the money.`);
108+
if (addMoneyResults.modifiedCount !== 1) {
109+
await session.abortTransaction();
110+
return;
111+
}
112+
113+
}, transactionOptions);
114+
115+
if (transactionResults) {
116+
console.log("The money was successfully transferred.");
117+
} else {
118+
console.log("The money was not transferred. The transaction was intentionally aborted.");
119+
}
120+
} catch (e) {
121+
console.log("The money was not transferred. 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+
}
128+

0 commit comments

Comments
(0)

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