Nodejs mysql transaction rollback not working

I am using Nodejs MySQL and tried to create database level transaction so that I can execute a bunch of statements in a batch and rollback if there is an error in any step. I tried to follow this tutorial.

My database module is:

let mysql = require('mysql') let keys = require('../config/keys') let util = require('util')  let pool = mysql.createPool({     connectionLimit: 20,     host: keys.connection.host,     user: keys.connection.user,     password: keys.connection.password,     database: keys.connection.database,     dateStrings: true     // debug:true                //Set this to true for verbose debugging. Leaving this to default for now cause it is creating too many messages at my console }) pool.getConnection((err, connection) => {     if (err) {         if (err.code === 'PROTOCOL_CONNECTION_LOST') {             console.error('Database connection was closed.')         }         if (err.code === 'ER_CON_COUNT_ERROR') {             console.error('Database has too many connections.')         }         if (err.code === 'ECONNREFUSED') {             console.error('Database connection was refused.')         }     }     if (connection) connection.release()     return })  pool.query = util.promisify(pool.query)  const connection = () => {     return new Promise((resolve, reject) => {         pool.getConnection((err, connection) => {             if (err) reject(err);              console.log("MySQL pool connected: threadId " + connection.threadId);              const query = (sql, binding) => {                 return new Promise((resolve, reject) => {                     connection.query(sql, binding, (err, result) => {                         if (err) reject(err);                         resolve(result);                     });                 });             };              const release = () => {                 return new Promise((resolve, reject) => {                     if (err) reject(err);                     console.log("MySQL pool released: threadId " + connection.threadId);                     resolve(connection.release());                 });             };             resolve({                 query,                 release             });         });     }); }; // const query = (sql, binding) => { //  return new Promise((resolve, reject) => { //      pool.query(sql, binding, (err, result, fields) => { //          if (err) reject(err); //          resolve(result); //      }); //  }); // }; module.exports = {     pool,     connection } 

In my route, I am trying to use the connection which should allow transaction:

const mysql = require('../../middleware/database')  async function buildCoreSchemas(){       const connection = await mysql.connection();          try{          await connection.query("START TRANSACTION");           await connection.query(`CREATE TABLE adjustreason (             AdjustID int NOT NULL AUTO_INCREMENT,             AdjustReason varchar(100) NOT NULL,             PRIMARY KEY (AdjustID)           )`)                await connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`)                   await connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`)           await connection.query("COMMIT");         }     catch(err){         await connection.query("ROLLBACK");         console.log(err)         return false     }     finally {     await connection.release();   } 

As you can see I my second insert statement is wrong as there is no column name called FAKE COLUMN. So, the error gets caught and I get the error message in my console:

Unknown column ‘FAKECOLUMN’ in ‘field list

But when I go and look at my database the transaction is not rollbacked because I can see that the first record is still there. What am I doing wrong?

Add Comment
1 Answer(s)

Ciao, try to modify code in this way:

connection.beginTransaction(function(err) {  if (err) { throw err; }    connection.query(`CREATE TABLE adjustreason (         AdjustID int NOT NULL AUTO_INCREMENT,         AdjustReason varchar(100) NOT NULL,         PRIMARY KEY (AdjustID)       )`, function (error, results, fields) {  if (error) {   return connection.rollback(function() {     throw error;   });  }  connection.query(`insert into adjustreason(AdjustReason) values('sdsds')`, function  (error, results, fields) {   if (error) {     return connection.rollback(function() {       throw error;     });   }   connection.query(`insert into adjustreason(FAKECOLUMN) values('sdsds')`, function   (error, results, fields) {   if (error) {     return connection.rollback(function() {       throw error;     });   }   connection.commit(function(err) {     if (err) {       return connection.rollback(function() {         throw err;       });     }     console.log('success!');   }); }); }); }); }); 

so you call connection.query inside connection.beginTransaction and if one of those query fails, you call connection.rollback. Otherwise connection.commit

Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.