MongoDB transactions
From MongoDB 4.0 they introduced transactions called 'Multi-Document transactions'.
What is Transaction
In MongoDB, each and every operation or query may modify a single document or multiple documents, For example, updateOne() operation updates one document is atomic, if we try to modify multiple documents by using a single operation like updateMany() is not atomic because of multiple documents are modifying in the collection. If we want to make multiple write operations as atomic we need a transaction.
In MongoDB 4.0 Multi-Document transactions support available for atomic operation on multiple writes.
Properties of Transaction
- When the transaction has committed all data operations on the transaction will commit automatically.
- If any operation fails, the transaction will fail.
- When the transaction has failed all data operations on the transaction will roll back automatically.
- Until transaction committed no write operation data will be exposed to the outside world.
In Version 4.0, Multi-Document transactions supports transaction on replica sets.
In Version 4.2, Multi-Document transactions supports transaction on replica sets, sharded clusters .
Operation on Transaction
- CRUD operation is allowed in a transaction.
- Write to a capped collection is also allowed.
- Write to system.* collections.
- For cursors created outside of a transaction, we can not use it inside of a transaction.
- For cursors created inside of a transaction, we can use in outside of a transaction also.
Example of transaction in mongo shell
// Prereq: Create collections. CRUD operations in transactions must be on existing collections.
db.getCollection('users').insert( {'userName': "Foo"}, { writeConcern: { w: "majority", wtimeout: 2000 } } );
db.getCollection('roles').insert( {'roleName':"Admin"}, { writeConcern: { w: "majority", wtimeout: 2000 } } );
// Start a session.
session = db.getMongo().startSession( { readPreference: { mode: "primary" } } );
coll1 = session.db.getCollection('users');
coll2 = db.getCollection('roles');
// Start a transaction
session.startTransaction( { readConcern: { level: "local" }, writeConcern: { w: "majority" } } );
// Operations inside the transaction
try {
coll1.insertOne( { 'userName': "Foo"} );
coll2.insertOne( { 'roleName':"Admin" } );
} catch (error) {
// Abort transaction on error
session.abortTransaction();
throw error;
}
// Commit the transaction using write concern set at transaction start
session.commitTransaction();
session.endSession();