Node-mssql: Error: Already connecting to database

Created on 19 Jul 2019  路  2Comments  路  Source: tediousjs/node-mssql

Expected behaviour:

Developer can post a json obect to an Azure function app to build a SQL query to return data for applications to consume. This works under light load but when under load testing it produces errors of ["Already connecting to database! Call close before connecting to different database."].

Trying to identify if our our call is the issue or if there is another underlying issue.

const pool = new sql.ConnectionPool({
    user: userName,
    password: password,
    server: sqlServer,
    database: sqlDatabase,
    options: {
        encrypt: true
    }
});

module.exports = async (query, singleReturn) => {
    try {
        if (!pool.connected)
            await pool.connect();

        var req = await pool.request();
        var result = await req.query(query); 

        await pool.close();

        return singleReturn ? result.recordset[0] : result.recordset;
    } catch (error) {
        throw error
    } finally {
        if (pool.connected)
            await pool.close()

    }
}

Software versions

  • NodeJS:
  • node-mssql: 5.1
  • SQL Server: Azure SQL
not-a-bug

Most helpful comment

Your problem is that you could invoke the function N times before the pool is connected, while the pool is actually connecting. Therefore you are queueing up multiple calls to await pool.connect();

You can use pool.connecting which tells you if a connection operation is already happening:

        let connPromise;
        if (!pool.connected) {
            if (!pool.connecting) {
                connPromise = await pool.connect();
            } else {
                await connPromise;
            }
        }

Finally, unless I am missing something, you want to keep the pool open for as long as possible. Remember the pool is not a connection per se; it is just a container for N connections. The whole purpose of pooling is to reuse connections and avoid connection overhead. Ergo, connecting on every function trigger is probably a bad idea.

I'm closing this as it isn't a defect with the library.

All 2 comments

Your problem is that you could invoke the function N times before the pool is connected, while the pool is actually connecting. Therefore you are queueing up multiple calls to await pool.connect();

You can use pool.connecting which tells you if a connection operation is already happening:

        let connPromise;
        if (!pool.connected) {
            if (!pool.connecting) {
                connPromise = await pool.connect();
            } else {
                await connPromise;
            }
        }

Finally, unless I am missing something, you want to keep the pool open for as long as possible. Remember the pool is not a connection per se; it is just a container for N connections. The whole purpose of pooling is to reuse connections and avoid connection overhead. Ergo, connecting on every function trigger is probably a bad idea.

I'm closing this as it isn't a defect with the library.

Thank you, made changes based on your suggestions and load testing is no longer produces errors

Was this page helpful?
0 / 5 - 0 ratings