node.jsnode-mysql

Node - Mysql Transaction is not rolling back if one query fails


I am trying to perform node-mysql transaction which has three query in total. All three are 'INSERT' queries. I intensionally write third query wrong to test rollback but transaction is making entry to database without fail for first two queries.

I know similar question has already been asked several times and I tried almost all of them but no luck

exports.registerNewUserTransaction = async (
  res,
  userToBeAdded,
  nameToBeAdded,
  emailToBeAdded)  => {
  const conn = await db.getConnection();
  await conn.beginTransaction();
  try {
    await this.insertOne('user', userToBeAdded);
    await this.insertOne('name', nameToBeAdded);
    await this.insertOne('email', emailToBeAdded);
    await conn.commit();
    res.status(200);
  } catch(err) {
    await conn.rollback();
    res.status(400);
  } finally {
    await conn.release();
  }
};

As you can see I am getting connection object from Pool, beginning the transaction and performing queries one by one. My third query has wrong column name, hence transaction should rollback but I see entry of first two queries. I would really appreciate the correct direction. node version: 12.8.0 mysql (running in docker): 8.0.15 mysql (npm version): 2.17.1


Solution

  • After struggling a lot, finally figured it out. Here's the answer:

    exports.registerNewUserTransaction = async (
      res,
      userToBeAdded,
      nameToBeAdded,
      emailToBeAdded)  => {
      const conn = await db.getConnection();
      // My first mistake was not to promisify connection query 
      conn.query = util.promisify(conn.query);
      await conn.beginTransaction();
      try {
        // My second mistake was not to use same connection
        await conn.query('INSERT INTO ...', userToBeAdded);
        await conn.query('INSERT INTO ...', nameToBeAdded);
        await conn.query('INSERT INTO ...', emailToBeAdded);
        await conn.commit();
        return res.status(200);
      } catch(err) {
        await conn.rollback();
        return res.status(400);
      } finally {
        await conn.release();
      }
    };
    

    Hope this might help someone!