An Exploration of the poignant history of mongoDB 4.0 Transaction rollback
- 2020-08-22 22:59:57
- OfStack
preface
The supervisor found out a few days ago that mongoDB had been upgraded to 4.0, and he couldn't wait to let me achieve the long-awaited transaction rollback. He found that there were still a lot of holes.
Here is how I upgraded my existing local mongoDB to support transaction rollback, share it out, please correct any mistakes!
Take mac, for example
Deploy mongodb transaction rollback
1. Preparation
Upgrade mongodb to 4.0.0
$ brew upgrade mongodb
Upgrade or install ES26en.js v3.1.0 or above
$ npm i mongodb --save-dev
pit
After upgrading above, when connecting mongo in ES36en. js,
It warns you to add one field to connect's option
useNewUrlParser:true
.
If you have user authentication, you need to add another field to option for connect
authSource: db where the user is, 1 generally admin
Otherwise, validation fails and no user error is found, such as
const mongoClient = await MongoClient.connect(mongoClientUrl, {
auth: {
user: config.dbUserName,
password: config.dbUserPassword,
},
authSource:'admin',
useNewUrlParser:true,
});
2. Transform an existing database into a replication set
Currently, transaction rollback can only operate on replicated sets; mongodb server alone cannot operate on transactions
Turn off all mongod
Add -replSet rs0 after normally starting mongod command, for example
$ mongod -dbpath ./db --port 27017 --replSet rs0
Open another shell and create an instance of mongo with a different port, for example
$ mongod -dbpath ./db_repl --port 27018 --replSet rs0
Connect to the mongo instance of 27017 and set
$ mongo
$ rs.initiate()
$ rs.add('localhost:27018');
complete
3. Write rollback code
A new method has been added to ES101en.js
export const getSession = async function() {
return await state.mongoClient.startSession();
};
Call this method each time before the mongo code needs to be rolled back to get the session flag to start rolling back
const session = await db.getSession();
session.startTransaction({
readConcern: {level: 'snapshot'},
writeConcern: {w: 'majority'},
});
Each time the method mongodb.js is called to manipulate the database, take session with you, for example
db
.collection(this.collecitonName)
.insertOne(doc,{session});
After you handle the error and feel the need to roll back, execute
await session.abortTransaction();
When you feel ok, start 1 and finish normally, execute
$ npm i mongodb --save-dev
0
There may be some encapsulated code in my code that has not been put up, which may not be understood. I just cite a chestnut to implement, specific code implementation can see reference link 1
4. To summarize
The useNewUrlParser attribute identifies the db required to authenticate the user in url and does not need to be specified before upgrading to 1, either after url or with authSource
A transaction rollback can only operate on a replicated set, and I guess the principle is this: first record the session of the primary node, and then roll back, find a snapshot of the data of the secondary node through this session, and then apply this snapshot to the primary node to achieve rollback. Of course, the actual situation should be quite complicated, otherwise mongoDB would not have taken 3 years to implement this operation.
5. Reference links
conclusion