Painful process of transaction rollback in testhole mongodb4.0

Time:2021-3-23

The supervisor found that mongodb has been upgraded to 4.0 a few days ago. He can’t wait for me to realize his long-awaited transaction rollback. He found that there are still many pitfalls!
The following is the process of upgrading my existing mongodb to support transaction rollback. If there are any mistakes, please correct them!
Take MAC as an example

Deploying mongodb transaction rollback

1. Preparation

  • Upgrade mongodb to 4.0.0
$ brew upgrade mongodb
  • Upgrade or install mongodb.js Over v3.1.0
$ npm i mongodb --save-dev
  • pit
    After the above upgrade, db.js When you connect Mongo,
    It will warn you to add a field in the option of connect
    useNewUrlParser:true
    At this time, if there is user authentication, you need to add another field in the option of connect
    Authsource: the DB of the user, generally admin
    Otherwise, it will report that the verification fails and the user’s error cannot be found, such as
    const mongoClient = await MongoClient.connect(mongoClientUrl, {
      auth: {
        user: config.dbUserName,
        password: config.dbUserPassword,
      },
      authSource:'admin',
      useNewUrlParser:true,
    });

2. Transform the existing database into a replica set

At present, transaction rollback can only be operated on the replica set, and a single mongodb server cannot operate transactions

  • Turn off all mongod
  • Add — replset rs0 after starting the mongod command, such as
$ mongod -dbpath ./db --port 27017 --replSet rs0
  • Open a shell again and create a Mongo instance with different ports, such as
$ mongod -dbpath ./db_repl --port 27018 --replSet rs0
  • Connect the Mongo instance of 27017 and set the
$ mongo
$ rs.initiate()
$ rs.add('localhost:27018');
  • complete

3. Write rollback code

  • stay db.js A new method has been added in
    export const getSession = async function() {
      return await state.mongoClient.startSession();
    };
  • Call this method to get session and start rolling back every time before the Mongo code that needs to be rolled back.
    const session = await db.getSession();
    session.startTransaction({
        readConcern: {level: 'snapshot'},
        writeConcern: {w: 'majority'},
    });
  • On each call mongodb.js When operating the database, you should bring session, such as
    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 think it’s all right, at the end of the normal together, execute
    await session.commitTransaction();
  • There may be some encapsulated code in my code that is not put on it, which may lead to incomprehensibility. I just give a chestnut to achieve, specific code implementation can see the reference link 1

4. Summary

  • The attribute usenewurlparser will identify the DB needed to verify the user in the URL. It does not need to be specified before upgrading, but it must be specified when upgrading to, whether it is after the URL or with authsource
  • Transaction rollback can only be operated on the replica set. I guess the principle of the implementation may be as follows: first record the session of the primary node, and then roll back. Through this session, find the data snapshot of the secondary node, and then apply the snapshot to the primary node to realize the rollback. Of course, the actual situation should be quite complicated, otherwise mongodb will not take three years to implement this operation.

5. Reference link

I’m just a front-end. Why torture my QAQ so much