Nodejs 运行mysql 模块后程序未结束问题,请问怎么修改?

Nodejs 运行mysql 模块后程序未结束问题,请问怎么修改?

// mysqldb-util.js var mysql = require(‘mysql’);

var pool = mysql.createPool({ host: ‘127.0.0.1’, user: ‘root’, password: ‘root’, port: ‘3306’, database: ‘nodesample’ });

exports.dataCenter = function(sql, fn) { // (callback && typeof(callback) === “function”) pool.getConnection(function (err, conn) { if (err) { console.log("POOL ==> " + err); return fn(err); } else { conn.query(sql, function (err, res) { conn.release(); return fn(res); }); } }); };

//mysqlDbTest.js var mysql = require(‘mysql’) , dbUtil = require(’./mysql-dbutil’);

var selectSQL = “select * from ?? where ID = ?”; var selectArr = [‘mytable’, ‘12204’]; selectSQL = mysql.format(selectSQL, selectArr);

dbUtil.dataCenter(selectSQL, function(data) { console.log(data); });

请问 运行node mysqlDbTest.js 时,光标输出数据后怎么还停着未结束?是因为连接未释放吗?怎么修改呢?多谢


5 回复

要自己结束掉,最初我没去处理这个问题,因为我直接用easymysql这个模块了,还自带链接池,不用close,自动归还。


在Node.js中运行MySQL模块时,如果程序没有按预期结束,通常是因为某些异步操作仍在进行中。在这种情况下,问题可能出在数据库连接池的使用上。为了确保程序能够正常结束,我们需要正确地处理所有异步操作。

以下是一些修改建议:

  1. 确保连接池中的连接被正确释放:在每个查询完成后,应该调用conn.release()来释放连接。
  2. 监听事件并关闭连接池:在所有异步操作完成后,监听'end'事件或显式地关闭连接池。

下面是修改后的代码示例:

mysqldb-util.js

var mysql = require('mysql');

var pool = mysql.createPool({
    host: '127.0.0.1',
    user: 'root',
    password: 'root',
    port: '3306',
    database: 'nodesample'
});

exports.dataCenter = function(sql, fn) {
    pool.getConnection(function (err, conn) {
        if (err) {
            console.log("POOL ==> " + err);
            return fn(err);
        } else {
            conn.query(sql, function (err, res) {
                conn.release(); // 释放连接
                return fn(err, res);
            });
        }
    });
};

// 添加一个方法来关闭连接池
exports.closePool = function() {
    pool.end(function (err) {
        if (err) {
            console.log("POOL close error: " + err);
        } else {
            console.log("POOL closed");
        }
    });
};

mysqlDbTest.js

var mysql = require('mysql')
, dbUtil = require('./mysqldb-util');

var selectSQL = "select * from ?? where ID = ?";
var selectArr = ['mytable', '12204'];
selectSQL = mysql.format(selectSQL, selectArr);

dbUtil.dataCenter(selectSQL, function(err, data) {
    if (err) {
        console.error(err);
    } else {
        console.log(data);
    }

    // 程序结束前调用closePool方法来关闭连接池
    dbUtil.closePool();
});

解释

  1. 释放连接:在dataCenter函数中,每次查询完成后都调用conn.release()来释放连接。
  2. 关闭连接池:在mysqldb-util.js中添加了一个closePool方法来关闭连接池。当所有的查询完成后,调用这个方法来确保连接池被正确关闭。
  3. 程序结束:在mysqlDbTest.js中,在回调函数执行完毕后调用dbUtil.closePool()来关闭连接池,从而确保程序可以正常结束。

通过这些修改,你的Node.js程序将能够正确地处理所有异步操作,并且在完成所有任务后正常退出。

pool.query() 好像也可以的,连接的获取和释放帮你做了,只是如果要用到其他例如事务处理的好像不行,还是得自己 getConnection

[@maxer028](/user/maxer028) 表示遇到同样得问题 请问下你解决了么

你的问题可能是由于Node.js进程没有正确退出导致的。尽管你已经释放了数据库连接,但整个Node.js进程可能还在等待一些异步操作完成。

你可以通过在回调函数执行完毕后手动结束Node.js进程来解决这个问题。具体来说,可以在回调函数中调用process.exit()来实现。不过需要注意的是,这种方法并不总是推荐,因为它可能会掩盖潜在的逻辑错误。更好的做法是确保所有异步操作都已完成后,再正常退出程序。

示例代码修改

mysqldb-util.js

var mysql = require('mysql');

var pool = mysql.createPool({
    host: '127.0.0.1',
    user: 'root',
    password: 'root',
    port: '3306',
    database: 'nodesample'
});

exports.dataCenter = function(sql, fn) {
    pool.getConnection(function (err, conn) {
        if (err) {
            console.log("POOL ==> " + err);
            return fn(err);
        } else {
            conn.query(sql, function (err, res) {
                conn.release();
                fn(res);
                // 确保所有异步操作完成后手动退出进程
                process.exit(0);
            });
        }
    });
};

mysqlDbTest.js

var mysql = require('mysql')
, dbUtil = require('./mysqldb-util');

var selectSQL = "select * from ?? where ID = ?";
var selectArr = ['mytable', '12204'];
selectSQL = mysql.format(selectSQL, selectArr);

dbUtil.dataCenter(selectSQL, function(data) {
    console.log(data);
});

解释

  • dataCenter函数的回调函数中,我们调用了process.exit(0)来确保Node.js进程在完成所有异步操作后正常退出。
  • 这种方法可以确保程序运行结束后立即退出,避免程序挂起。

不过,更优雅的做法是检查是否有其他异步操作需要处理,或者在所有异步操作完成后自然地退出程序。

回到顶部