module.exports范围和node-mysql

时间:2013-10-26 12:21:32

标签: javascript mysql node.js

我有连接到db的database.js文件并管理连接我导出连接并在我的应用程序中重用它

    var mysql = require('mysql');

    pool = mysql.createPool({
        host: cfg.mysql.host,
        user: cfg.mysql.user,
        password: cfg.mysql.pass,
        database: cfg.mysql.db,
        port: cfg.mysql.port
    });


    function handleDisconnect() {
    pool.getConnection(function(err, cnt) {
    module.exports.connection = cnt;
    });

    pool.on('error', function (err) {
      console.log(err);
    });
    };

    handleDisconnect();
    process.on('uncaughtException', function (err) {
      console.error(err.code);
    if(err.code === "PROTOCOL_CONNECTION_LOST")
    handleDisconnect();
      console.log("Node NOT Exiting...");
    });

app.js

    var db = require('./database');
     app.get('/test', function(req, res) {
        db.connection.query('SELECT * from table', function(err, result) {
           console.log(result);
          });
        }

这很好用。我的问题是当mysql服务器断开连接时。我通过调用handleDisconnect()函数来获取新连接来处理此错误。但是,当发生这种情况时,当我导航到我的浏览器/测试

时,我的app.js中的连接未定义
TypeError: Cannot call method 'query' of undefined

思想?

3 个答案:

答案 0 :(得分:2)

您可以在数据库服务器上的每个查询之后将连接简单地放回池中 这是一个例子

<强> db.js

var mysql = require('mysql');
var pool  = mysql.createPool({
  host     : 'localhost',
  user     : 'root',
  password : 'root',
  database : 'test',
  port: 8889
});

exports.getConnection = function(callback) {
    pool.getConnection(function(err, connection) {
        callback(err, connection);
    });
};

<强> app.js

var db = require('./db');
var http = require("http");
var server = http.createServer(function(request, response) {
    db.getConnection(function(err, connection){
        if(!err){
            connection.query('SELECT * from users' , function(err, rows) {
                var users = '';
                for (var i = 0; i < rows.length; i++) {
                    users += rows[i].name + "<br />";
                }
                connection.release(); // always put connection back in pool after last query
                response.writeHead(200, {"Content-Type": "text/html"});
                response.write("<!DOCTYPE html>");
                response.write("<html>");
                response.write("<head>");
                response.write("<title>Hello World Page</title>");
                response.write("</head>");
                response.write("<body>");
                response.write(users);
                response.write("</body>");
                response.write("</html>");
                response.end();
           });
        }else{
            response.writeHead(200, {"Content-Type": "text/html"});
            response.write("<!DOCTYPE html>");
            response.write("<html>");
            response.write("<head>");
            response.write("<title>Hello World Page</title>");
            response.write("</head>");
            response.write("<body>");
            response.write(err.toString());
            response.write("</body>");
            response.write("</html>");
            response.end();
        }
    });
});
server.listen(9999);
console.log("Server is listening localhost:9999");

答案 1 :(得分:1)

更新:请参阅下面的第一条评论,以更正我对此问题的理解。我将此回复留下,而不是删除它,因为它触及了多个问题。

您无法继续重新分配给module.exports。它不起作用,因为导出只在require()时发生一次(事实上,我怀疑上面的代码完全可以工作,因为pool.getConnection同步执行,即在回调中分配给module.exports通常不安全) 。这是正在发生的事情:

在app.js中你执行:var db = require('./database');

这不存储对module.exports(of database.js)的引用,而是存储分配给module.exports的对象(即连接对象)。当该对象因断开连接而被销毁时,app.js中的变量“db”指的是什么(请注意,node-mysql文档很清楚,您无法重用连接对象)。你真正想做的是将一个新的连接对象返回给app.js,但这是不可能的,因为app.js调用只需要一次。

我知道你想隐藏app.js的连接重建。一种方法是将node-mysql连接对象包装在您自己的database.js对象中,并将后者返回给app.js.这个包装对象可以在调用query()方法时从池中获取连接,然后调用获取连接的query()方法。等等。

答案 2 :(得分:0)

首先检查pool.getConnection中的handleDisconnect是否会引发错误。由于在重新连接之前没有内置超时以防连接丢失,因此可能会因为同样的问题立即调用pool.getConnection失败。

此外,在连接丢失和handleDisconnect重新连接之间,任何传入的HTTP请求都无法执行数据库查询,因此在尝试运行查询之前应检查db.connection是否实际有效。

那,或者您也需要处理Express路由中的错误,例如使用错误处理程序路由(应该放在路由/中间件设置的最后位置):

// middleware setup
...
// routes setup
...
// finally:
app.use(function(err, req, res, next) {
  res.send(500, err.message); // or whatever you want to send back in case of errors.
});