nodejs mysql and handling transactions - code design

Viewed 112

so, I am little new to NodeJS and here is the issue. We all know NodeJS is single threaded and thus we use async operations for any I/O operation like file reading and database queries

consider the following code which basically opens a transaction, makes some DB insert and commit :

    const mysql = require ("mysql2/promise")
    const pool   = mysql.createPool({
        host: "localhost",
        user: "<myuser>",
        password: "<mypass>",
        database: "<mydb>",
        connectionLimit: 10,
    });

    const test = async function () {
        let conn = await pool.getConnection()
        await conn.beginTransaction()
        await conn.execute("insert into test.temp1 (a) values(?)", [1])
        await conn.execute("insert into test.temp1 (a) values(?)", [2])
        await  conn.commit()
        await conn.release()
    }
    test()

this is all fine and dandy, but real live code structure is more complex. One query might update a user balance, another query might insert a log record and another query to insert a transactions record in different locations in code (reusability) )and all of that in one transaction.

so, consider the below code which is a modified version of the above code:

const pool   = mysql.createPool({
        host: "localhost",
        user: "<myuser>",
        password: "<mypass>",
        database: "<mydb>",
        connectionLimit: 10,
});

const function1 = async function (params){
    let conn = await pool.getConnection()
    await conn.execute("insert into test.temp1 (a) values(?)", [params])
    throw new Error("error in my code")
}
const test = async function () {
    let  conn = await pool.getConnection()
    await conn.beginTransaction()
    await function1(1)
    await function1(2)
    await  conn.commit()
    await conn.release()
}
test().catch(async function (err){
    let  conn = await pool.getConnection()
    conn.rollback()
    console.log(err)
})

the issue is that the inner calls are using a different connection then the connection that opened the transaction and thus the transaction block is not working

I cannot store the connection in some static resource and use it in my inner functions because it is single threaded and shared by all running code

is my solution to pass around the connection to all classes/functions? This is not much fun

any other design pattern that I should use to better support transactions?

0 Answers
Related