Nodejs:使用了node-mysql的代码无法自动停止

Nodejs:使用了node-mysql的代码无法自动停止

自己写的一段demo…

// db.js
var mysql = require('mysql');

module.exports = function () {
    var pool = mysql.createPool({
        host: "localhost",
        user: 'xxx',
        password: 'xxx',
        database: 'xxx',
    });

    return pool;
}();


// valid.js
var pool = require('./db.js');

module.exports = function () {
    return {
        isProjectOwner: function (uid, pid, callback) {
            pool.getConnection(function (err, connection) {
                if (err) {
                    callback(err, null);
                }

                var sql = '.....';
                connection.query(sql, [pid, uid], function (err, res, fields) {
                    if (err) {
                        callback(null, false); // Maybe attack
                    }

                    console.log(res);

                    if (res.length) {
                        callback(null, true);
                    } else {
                        callback(null, false);
                    }

                    connection.release();
                });
            });
        },
    };
}();

// tdb.js
var valid = require('./valid.js');

valid.isProjectOwner(2, 1, function (err, result) {
    if (err) {
        throw err;
    }

    console.log(result);
});

在Terminal中运行tdb.js

> $ node tdb.js
[]
false

但是,不使用Ctrl+C无法结束进程。。

求教各位大大,谢谢~


4 回复

你遇到的问题是因为你的 Node.js 进程没有明确的退出机制。在 Node.js 中,当你创建了一个数据库连接池并且没有显式地关闭它时,进程不会自动退出。这是因为 Node.js 进程会等待所有活动的 I/O 操作完成之后才会退出。

你可以通过在 db.js 文件中添加一个函数来手动关闭连接池,并在主程序中调用该函数来确保进程能够正常退出。

以下是修改后的代码:

db.js

var mysql = require('mysql');

module.exports = function () {
    var pool = mysql.createPool({
        host: "localhost",
        user: 'xxx',
        password: 'xxx',
        database: 'xxx',
    });

    // 添加一个关闭连接池的方法
    module.exports.closePool = function () {
        pool.end(function (err) {
            if (err) {
                console.error('Error closing the pool:', err.stack);
            } else {
                console.log('Connection pool closed.');
            }
        });
    };

    return pool;
}();

tdb.js

var valid = require('./valid.js');
var db = require('./db.js');

valid.isProjectOwner(2, 1, function (err, result) {
    if (err) {
        throw err;
    }

    console.log(result);

    // 在操作完成后关闭连接池
    db.closePool();
});

解释

  1. 关闭连接池:在 db.js 中,我们添加了一个 closePool 方法,用于关闭连接池。这将释放所有活动的连接并停止连接池。
  2. 调用关闭方法:在 tdb.js 的回调函数中,我们在处理完数据库查询后调用了 db.closePool() 方法。这确保了在执行完所有操作后连接池被正确关闭,从而使进程可以正常退出。

通过这种方式,你可以确保在完成所有数据库操作后,进程能够正常退出,而不需要使用 Ctrl+C 强制终止。


把pool关闭掉就可以正常退出了

了解了~谢谢~

这个问题是因为你的 Node.js 应用没有监听到退出信号(如 SIGINT),因此当您按下 Ctrl+C 时,应用没有正确地关闭 MySQL 连接池。你可以通过监听这些信号来确保资源被正确释放。

你可以修改 db.js 文件,在其中添加对 SIGINT 信号的监听处理。下面是一个简单的示例:

// db.js
var mysql = require('mysql');
var pool = mysql.createPool({
    host: "localhost",
    user: 'xxx',
    password: 'xxx',
    database: 'xxx',
});

process.on('SIGINT', function() {
    pool.end(function(err) {
        if (err) {
            console.error('Failed to close the pool:', err);
        } else {
            console.log('MySQL pool closed.');
        }
        process.exit();
    });
});

module.exports = pool;

上述代码中,我们添加了一个事件监听器来监听 SIGINT 信号,当收到该信号时,会调用 pool.end() 方法来关闭所有活动连接并释放它们。然后调用 process.exit() 来安全退出程序。

这样,在按下 Ctrl+C 后,你的 Node.js 应用将会正确地关闭 MySQL 连接池,并且能够正常退出。

回到顶部