23 กรกฎาคม 2568

MongoDB Transactions with mongosh: A Step-by-Step Guide

MongoDB Transactions with mongosh: A Step-by-Step Guide

MongoDB transactions allow you to execute multiple operations as a single, atomic unit. This means either all operations within the transaction succeed and are applied to the database, or if any operation fails, all changes are rolled back. This guide will walk you through the process using the mongosh shell.



Prerequisites

Before you begin, ensure you have:
  • A running MongoDB instance (version 4.0 or higher, as transactions were introduced in 4.0).
  • mongosh (MongoDB Shell) installed and connected to your MongoDB instance.
  • A sample database and collection. For this guide, we'll assume a database named a_test and a collection named student.
Let's start by ensuring we have some initial data in our student collection:

// Switch to the database 
use a_test; 

 // Insert a sample document if it doesn't exist 
db.student.insertOne({ _id: "s1", name: "Alice", age: 10, grade: "A" }); 

 // Verify the initial data 
db.student.findOne({ _id: "s1" });



Step-by-Step Transaction Example

Follow these steps to perform a transaction:

1. Create a MongoDB Session

Transactions in MongoDB are associated with a session. First, you need to create one.

// Create a new client session 
session = db.getMongo().startSession();


2. Start the Transaction

Once the session is created, you can initiate a transaction on it. It's good practice to define readConcern and writeConcern for the transaction to ensure data consistency and durability.

  • readConcern: { "level": "snapshot" }: Ensures that reads within the transaction see a consistent snapshot of the data, preventing dirty reads and non-repeatable reads.
  • writeConcern: { "w": "majority" }: Ensures that write operations are acknowledged by the majority of the replica set members, providing strong durability guarantees.
// Start the transaction with specified read and write concerns 
session.startTransaction({ 
  "readConcern": { "level": "snapshot" }, 
  "writeConcern": { "w": "majority" } 
});


3. Get the Collection within the Session

All operations within the transaction must be performed on collections obtained through the session object.

// Get the 'student' collection from the 'a_test' database within the session
coll = session.getDatabase('a_test').getCollection('student');



4. Check Data (Pre-Update)

You can perform read operations within the transaction. This read will reflect the state of the data before any modifications made within the current transaction, but it will see the latest committed data from outside the transaction.

// Find the document with _id "s1" 
coll.findOne({ _id: "s1" }); 

// Expected output (assuming initial state): { _id: "s1", name: "Alice", age: 10, grade: "A" }


5. Update Data within the Transaction

Now, perform your write operation. This change is not yet visible to other sessions or outside this transaction. It's only staged within the current transaction's context.

// Update the 'age' field for the document with _id "s1" 
coll.findOneAndUpdate({ _id: "s1" }, { $set: { age: 11 } });


6. Check Data Again (Within Transaction)

If you check the data again within the same transaction, you will see the updated value. This demonstrates that changes are visible locally within the transaction's scope before being committed globally.

// Check the document again within the transaction 
coll.findOne({ _id: "s1" }); 

// Expected output: { _id: "s1", name: "Alice", age: 11, grade: "A" }


7. Global Verification (Before Commit/Abort)

To confirm that the changes are not yet public, open a new mongosh window or session and query the same document. You will see the original age value.

// In a NEW mongosh window/session: 
use a_test; 
db.student.findOne({ _id: "s1" }); 

// Expected output: { _id: "s1", name: "Alice", age: 10, grade: "A" }



Finalizing the Transaction: Abort or Commit

You have two options to finalize the transaction: aborting it (rolling back changes) or committing it (making changes permanent).

Option A: Abort Transaction (Rollback)

If you decide to cancel the changes made within the transaction, you can abort it. All modifications made since startTransaction() will be discarded.

// Abort the transaction 
session.abortTransaction();
print("Transaction aborted. Changes rolled back.");


After aborting, verify the result in the global database. The data will revert to its state before the transaction began.

// Verify the result in the global database (in any mongosh window) 
use a_test; 
db.student.findOne({ _id: "s1" }); 

// Expected output: { _id: "s1", name: "Alice", age: 10, grade: "A" }


Option B: Commit Transaction (Apply Changes)

If the operations within the transaction were successful and you want to make the changes permanent and visible to all other sessions, you commit the transaction.

// Commit the transaction 
session.commitTransaction(); 
print("Transaction committed. Changes applied to the database.");


After committing, verify the result in the global database. The data will now reflect the changes made within the transaction.

// Verify the result in the global database (in any mongosh window) 
use a_test; 
db.student.findOne({ _id: "s1" }); 

// Expected output: { _id: "s1", name: "Alice", age: 11, grade: "A" }



Important Notes on Transactions
  • Replica Sets Only: Transactions are only supported on replica sets. They are not available on standalone MongoDB instances.
  • Sharded Clusters: Transactions are also supported on sharded clusters starting from MongoDB 4.2.
  • Size Limitations: There are limitations on the number of operations and total document size within a single transaction.
  • Error Handling: In a real application, you would wrap transaction operations in try-catch blocks to handle potential errors and ensure abortTransaction() is called if an error occurs.
  • Session Management: Always ensure you close or end sessions properly in your application code to free up resources. In mongosh, the session is automatically managed when you close the shell or if it's explicitly ended.

This guide provides a foundational understanding of using transactions in MongoDB with mongosh.

ไม่มีความคิดเห็น:

แสดงความคิดเห็น

บทความยอดนิยม (ล่าสุด)

บทความยอดนิยม (1 ปีย้อนหลัง)