2013-10-26 3 views
3

У меня есть database.js файл, который подключается к БД и управлять подключениями экспортировать соединение и повторно использовать его в моем приложенииmodule.exports сферы и узел-MySQL

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 

Мысли?

ответ

0

Начинающий отзыв pool.getConnectionhandleDisconnect. Вы ошиблись. Поскольку вы не создали тайм-аут, прежде чем повторно подключаться, если соединение потеряно, есть вероятность, что сразу же вызов pool.getConnection завершится неудачно из-за той же проблемы.

Кроме того, между моментом, когда соединение теряется, и handleDisconnect повторное подключение, любые входящие HTTP-запросы не могут выполнять запросы к базе данных, поэтому необходимо проверить, действительно ли db.connection, прежде чем пытаться выполнить запрос.

Это, или вам нужно обрабатывать ошибки в ваших Экспресс маршрутов тоже, например, с маршрута обработчика ошибок (который должен быть размещен где-то в последний раз в вашем маршруте/установки промежуточного программного обеспечения):

// 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. 
}); 
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

UPDATE: Смотрите ниже первый комментарий к коррекции на моих [СУИ] понимание проблемы. Я оставляю этот отзыв, а не удаляю его, поскольку он затрагивает несколько вопросов.

Вы не можете сохранить переназначение в module.exports. Это не сработает, потому что экспорт происходит только один раз в require() (на самом деле, я подозреваю, что ваш код выше работает вообще только потому, что pool.getConnection выполняется синхронно, т.е. присвоение module.exports в обратном вызове обычно не безопасно) , Вот что происходит:

В app.js вы: var db = require('./database');

Это сохраняет ссылку не на module.exports (от database.js), но к объекту, присвоенных module.exports (т.е. объект соединения). Когда этот объект уничтожается из-за отключения, переменная «db» в app.js ничего не говорит (обратите внимание, что документы node-mysql понятны, что вы не можете повторно использовать объект соединения). То, что вы действительно хотите сделать, - это вернуть новый объект подключения в app.js, но это невозможно, потому что вызовы app.js требуют только один раз.

Я понимаю, что вы хотите скрыть восстановление соединения с app.js.Один из способов сделать это - обернуть объект соединения node-mysql в свой собственный объект database.js и вернуть его в app.js. Этот обернутый объект может получить соединение из пула при вызове метода query(), а затем вызвать метод query() полученного соединения. Скоро.

+1

Соединение не привязано к 'module.exports', оно назначено' module.exports.connection', поэтому должно работать нормально (хотя я согласен, что текущая настройка немного сомнительна). – robertklep

+0

Хороший улов, я этого не заметил. – ravi

Смежные вопросы