Create Multi-Document Transactions in MongoDB for Node.js Applications
A multi-document transaction is a group of database operations that will be completed together as a unit or not at all. They are used when a group of related operations must either all succeed or fail together, which is a property called atomicity.
Let's go through the code to create a transaction step by step: We start the transaction by using the session’s withTransaction()
method. We then define the sequence of operations to perform inside the transactions, passing the session
object to each operation in the transactions.
Create variables used in the transaction.
// Collections const accounts = client.db("bank").collection("accounts") const transfers = client.db("bank").collection("transfers") // Account information let account_id_sender = "MDB574189300" let account_id_receiver = "MDB343652528" let transaction_amount = 100
Start a new session.
const session = client.startSession()
Begin a transaction with the
WithTransaction()
method on the session.const transactionResults = await session.withTransaction(async () => { // Operations (Step 4 - 8) will go here })
Update the
balance
field of the sender’s account by decrementing thetransaction_amount
from thebalance
field.const senderUpdate = await accounts.updateOne( { account_id: account_id_sender }, { $inc: { balance: -transaction_amount } }, { session } )
Update the
balance
field of the receiver’s account by incrementing thetransaction_amount
to thebalance
field.const receiverUpdate = await accounts.updateOne( { account_id: account_id_receiver }, { $inc: { balance: transaction_amount } }, { session } )
Create a transfer document and insert it into the
transfers
collection.const transfer = { transfer_id: "TR21872187", amount: 100, from_account: account_id_sender, to_account: account_id_receiver, } const insertTransferResults = await transfers.insertOne(transfer, { session })
Update the
transfers_complete
array of the sender’s account by adding thetransfer_id
to the array.const updateSenderTransferResults = await accounts.updateOne( { account_id: account_id_sender }, { $push: { transfers_complete: transfer.transfer_id } }, { session } )
Update the
transfers_complete
array of the receiver’s account by adding thetransfer_id
to the array.const updateReceiverTransferResults = await accounts.updateOne( { account_id: account_id_receiver }, { $push: { transfers_complete: transfer.transfer_id } }, { session } )
Log a message regarding the success or failure of the transaction.
if (transactionResults) { console.log("Transaction completed successfully.") } else { console.log("Transaction failed.") }
Catch any errors and close the session.
catch (err) { console.error(`Transaction aborted: ${err}`) process.exit(1) } finally { await session.endSession() await client.close() }
By default, a multi-document transaction has a 60-second time limit. This means that MongoDB will automatically cancel any multi-document transaction that runs for more than 60 seconds.