【问题标题】:Keeping mysql connection on Express在 Express 上保持 mysql 连接
【发布时间】:2018-06-06 20:49:30
【问题描述】:

所以我对 nodejs 和 express 还是很陌生。我正在尝试创建一项服务,我注意到我不能简单地通过再次声明 connection.connect() 来保持 mysql 连接。所以我想出了这种继续连接的方式,但我不确定这是否是保持连接的正确方式。大家可以看看代码中间的注释部分吗?

app.get('/keyboard', function(req, res){
    connection.connect();
    connection.query("SELECT `hour` from timetable WHERE `reserved` = '0'", function(err, rows, fields){

            if(err) throw err;
            var buttons = [];
            for(var i = 0; i < rows.length; i++){

                    buttons.push(rows[i].hour);
            }

            console.log("available time: " + buttons);

            var return_data = {

                    "type"    : "buttons",
                    "buttons" : buttons
            };
            //console.log(return_data);
            res.send(return_data);

    });

    connection.end(); // connection ends here
    //connection.connect() doesn't create a new connection.
    connection = mysql.createConnection({ // another connection like this?
            host     : 'localhost',
            user     : 'user',
            password : 'pw',
            database : 'db'
    });
});

【问题讨论】:

    标签: javascript mysql node.js express connection-pooling


    【解决方案1】:

    您可以使用node-mysql-pool npm 模块使用轮询方法创建连接。

    var MySQLPool = require("mysql-pool").MySQLPool;
    var pool = new MySQLPool({
      poolSize: 4,// it can be number of connections
      user:     'root',
      password: 'root',
      database: 'test'
    });
    
    pool.query("SELECT 'Hello, World!' AS hello", function(err, rows, fields) {
      if(err) throw err;
      console.log(rows[0].hello);
    });
    
    for(var i = 0; i < 10; ++i) {
      pool.query("SELECT SLEEP(2), ? AS i", [i], function(err, rows, fields) {
        if(err) throw err;
        console.log("Slept: " + rows[0].i);
      });
    }
    

    【讨论】:

    • 如果除了指向另一个答案的链接之外,您没有提供任何其他信息,那么它更有可能是评论,并且链接的答案所属的问题可能是重复的。除此之外,如果对服务器有许多并行请求,则仅对应用程序使用一个连接会导致性能下降。
    • 感谢您提供新信息。我想我需要多看看池化。
    【解决方案2】:

    在这种情况下,您应该考虑使用 mysql 库提供的池功能。池将接管管理连接的任务。

    var mysql = require('mysql');
    var pool = mysql.createPool({ // another connection like this?
      host: 'localhost',
      user: 'user',
      password: 'pw',
      database: 'db',
      connectionLimit : 10 // its depends on requirement  
    });
    
    
    app.get('/keyboard', function(req, res) {
      pool.query("SELECT `hour` from timetable WHERE `reserved` = '0'", function(err, rows, fields) {
    
        if (err) throw err;
    
        var buttons = [];
        for (var i = 0; i < rows.length; i++) {
          buttons.push(rows[i].hour);
        }
    
        console.log("available time: " + buttons);
    
        var return_data = {
    
          "type": "buttons",
          "buttons": buttons
        };
        //console.log(return_data);
        res.send(return_data);
      });
    })
    

    您可以像使用常规连接一样使用池,不同之处在于 mysql 模块会在每次调用池对象时从其池中请求一个新连接,并在查询完成后释放该连接。

    如果您需要使用 Transactions,如果您需要针对每个连接状态的使用执行另一种类型的多次查询,这一点很重要。例如。这样的事情可能会失败,或者出现意外行为:

    pool.query("START TRANSACTION")
    pool.query("SELECT ...") // some query
    pool.query("COMMIT")
    

    对于这种情况,您需要以这种方式编写它,但您需要使用 connection.release(); 将连接释放回池

    pool.getConnection(function(err, connection) {
      connection.query("START TRANSACTION")
      pool.query("SELECT ...") // some query
      connection.query("COMMIT", function() {
        connection.release();
      })
    });
    

    您可以使用connectionLimit 为池定义连接限制,如果您想控制/限制 mysql 服务器上的负载,这会很方便。

    (详情请见Pooling connections

    【讨论】:

    • 感谢详细解释!所以你的意思是如果我使用池,我不需要担心打电话给connection.end(),对吧?
    • @hklee93 啊抱歉,对于getConnection 场景,您需要使用connection.release(); 将连接释放回池。但是如果你只在池中直接调用查询函数(pool.query),那么你不需要使用releaseend
    • 非常感谢!让我过去试一试
    猜你喜欢
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2023-03-16
    • 2012-05-22
    • 2018-11-06
    相关资源
    最近更新 更多