2
connection.query(`START TRANSACTION;`, async function (err) {
  if (err) {
    req.flash("flash", "Something went wrong while deleting. Try again.");
    return res.redirect("back");
  } else {
    await connection.query(
      `INSERT INTO... ; SELECT LAST_INSERT_ID();`,
      async (error, results1) => {
        if (error) {
          await connection.query(`ROLLBACK;`, function (err) {
            req.flash("flash", "There was an error while posting.");
            return res.redirect("/post");
          });
        } else {
          var post_id = await results1[0].insertId;
          await connection.query(
            `INSERT INTO...`,
            [],
            async (error, results) => {
              if (error) {
                await connection.query(`ROLLBACK;`, function (err) {
                  req.flash("flash", "There was an error while posting.");
                  return res.redirect("/post");
                });
              } else {
                await connection.query(
                  `INSERT INTO...`,
                  async (error, results) => {
                    if (error) {
                      await connection.query(`ROLLBACK;`, function (err) {
                        req.flash("flash", "There was an error while posting.");
                        return res.redirect("/post");
                      });
                    }
                    await connection.query(`ROLLBACK;`, function(err){
                    req.flash("flash", "Went through...");
                    return res.redirect("back");
                 })
         ...
});

First I start the transaction. Then I have the code in the middle to insert data into 3 tables. I wanted to test the rollback which is supposed to undo everything after START TRANSACTION but it didn't do anything. What did I do wrong?

(The code works by itself so please ignore if I missplaced any brackets).

Janez Kranjski
  • 115
  • 2
  • 10

2 Answers2

3

The problem was that I was using a pool directly. You need to get a new connection and then use that to make all the queries and transactions. That is also the reason beginTransaction wasn't working for me before. What I should have done is:

connection.getConnection(function(err, con) {
    con.query...
    con.beginTransaction()...
    con.query..
    con.rollback()...
})
Janez Kranjski
  • 115
  • 2
  • 10
0

You can check the multiple-transaction-manager library to manage your transaction.

https://www.npmjs.com/package/@multiple-transaction-manager/mysql

Example;

// init manager & context
const txnMngr: MultiTxnMngr = new MultiTxnMngr();
const mysqlContext = new MysqlDBContext(txnMngr, pool);

// Add first step
mysqlContext.addTask("DELETE FROM test_table");

// Add second step
mysqlContext.addTask("INSERT INTO test_table(id, name) VALUES (:id, :name)", { "id": 1, "name": "Dave" });

// Add third step
mysqlContext.addTask("INSERT INTO test_table(id, name) VALUES (:id, :name)", { "id": 2, "name": "Kevin" });

// jest test
await expect(txnMngr.exec()).resolves.not.toBeNull();
Kemal Kaplan
  • 932
  • 8
  • 21