调用quit后不能排队握手
在这里,我正在做,可以提出一些基本的错误,一般来说,我已经实现了这样的代码:
module.exports = { getDataFromUserGps: function(callback) { connection.connect(); connection.query("SELECT * FROM usergps", function(err, results, fields) { if (err) return callback(err, null); return callback(null, results); } ); connection.end(); }, loginUser: function(login, pass, callback) { connection.connect(); connection.query( "SELECT id FROM users WHERE login = ? AND pass = ?", [login, pass], function(err, results, fields) { if (err) return callback(err, null); return callback(null, results); } ); connection.end(); }, getUserDetails: function(userid, callback) { connection.connect(); connection.query( "SELECT * FROM userProfilDetails LEFT JOIN tags ON userProfilDetails.userId = tags.userId WHERE userProfilDetails.userid = ?", [userid], function(err, results, fields) { if (err) return callback(err, null); return callback(null, results); } ); connection.end(); }, addTags: function(userId, tags) { connection.connect(); connection.query( "INSERT INTO tag (userId, tag) VALUES (?, ?)", [userId, tags], function(err, results, fields) { if (err) throw err; } ) connection.end(); } }
而一切都很好,但只有第一次,如果我想第二次“使用”查询,我收到他的错误:
调用quit后不能排队握手
我试过不要.end()连接,但它没有帮助
提前致谢
拉德克
如果使用node-mysql模块,只需删除.connect和.end。 刚才自己解决了这个问题。 显然他们在最后一次迭代中插入了不必要的代码,这个代码也被窃听了。 如果您已经运行createConnection调用,则不需要连接
根据:
-
修复节点Mysql“错误:调用退出后无法排队握手”:
http://codetheory.in/fixing-node-mysql-error-cannot-enqueue-handshake-after-invoking-quit/
TL; DR您需要在每次断开连接后调用
createConnection
方法来build立新的连接。
和
注意:如果您正在提供Web请求,那么您不应该在每个请求中都结束连接。 只需在服务器启动时创build一个连接,并使用连接/客户端对象来查询所有的时间。 您可以侦听错误事件来处理服务器断开连接和重新连接的目的。 完整代码在这里 。
从:
-
Readme.md – 服务器断开连接:
它说:
服务器断开连接
由于networking问题,服务器计时或服务器崩溃,您可能会失去与MySQL服务器的连接。 所有这些事件被认为是致命的错误,并将有
err.code = 'PROTOCOL_CONNECTION_LOST'
。 有关更多信息,请参阅error handling部分。处理这种意外断开的最佳方式如下所示:
function handleDisconnect(connection) { connection.on('error', function(err) { if (!err.fatal) { return; } if (err.code !== 'PROTOCOL_CONNECTION_LOST') { throw err; } console.log('Re-connecting lost connection: ' + err.stack); connection = mysql.createConnection(connection.config); handleDisconnect(connection); connection.connect(); }); } handleDisconnect(connection);
正如你在上面的例子中看到的,通过build立一个新的连接重新连接一个连接。 一旦终止,现有的连接对象不能通过devise重新连接。
使用Pool时,断开的连接将从池中移除,释放空间,以便在下一次getConnection调用时创build新连接。
我调整了函数,使得每次需要连接时,初始化函数自动添加处理程序:
function initializeConnection(config) { function addDisconnectHandler(connection) { connection.on("error", function (error) { if (error instanceof Error) { if (error.code === "PROTOCOL_CONNECTION_LOST") { console.error(error.stack); console.log("Lost connection. Reconnecting..."); initializeConnection(connection.config); } else if (error.fatal) { throw error; } } }); } var connection = mysql.createConnection(config); // Add handlers. addDisconnectHandler(connection); connection.connect(); return connection; }
初始化连接:
var connection = initializeConnection({ host: "localhost", user: "user", password: "password" });
小build议:这可能不适用于每个人,但我遇到了涉及范围的小问题。 如果OP觉得这个编辑是不必要的,那么他/她可以select删除它。 对我来说,我不得不在initializeConnection
更改一行,这是var connection = mysql.createConnection(config);
只是简单而已
connection = mysql.createConnection(config);
原因是如果connection
是程序中的一个全局variables,那么之前的问题就是在处理一个错误信号时你正在创build一个新的connection
variables。 但是在我的nodejs代码中,我一直使用相同的全局connection
variables来运行查询,因此新connection
将会在initalizeConnection
方法的本地范围内丢失。 但是在修改中,它确保全局connection
variables被重置。这可能是相关的,如果遇到问题已知
致命错误后无法排队查询
尝试执行查询失去连接后,然后成功重新连接。 这可能是OP的一个错字,但我只是想澄清一下。
我遇到了同样的问题,Google在这里引导我。 我同意@Ata,只是删除end()
是不正确的。 进一步谷歌search后,我认为使用pooling
是一个更好的方法。
关于池的node-mysql文档
就像这样:
var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err, connection) { connection.query( 'bla bla', function(err, rows) { connection.release(); }); });
我觉得这个问题和我的相似:
- 连接到MySQL
- 结束MySQL服务(不应该退出节点脚本)
- 启动MySQL服务,Node重新连接到MySQL
- 查询DB – > FAIL(致命错误后无法排队查询)
我通过使用promises(q)重新创build一个新的连接来解决这个问题。
MySQL的-con.js
'use strict'; var config = require('./../config.js'); var colors = require('colors'); var mysql = require('mysql'); var q = require('q'); var MySQLConnection = {}; MySQLConnection.connect = function(){ var d = q.defer(); MySQLConnection.connection = mysql.createConnection({ host : 'localhost', user : 'root', password : 'password', database : 'database' }); MySQLConnection.connection.connect(function (err) { if(err) { console.log('Not connected '.red, err.toString().red, ' RETRYING...'.blue); d.reject(); } else { console.log('Connected to Mysql. Exporting..'.blue); d.resolve(MySQLConnection.connection); } }); return d.promise; }; module.exports = MySQLConnection;
mysqlAPI.js
var colors = require('colors'); var mysqlCon = require('./mysql-con.js'); mysqlCon.connect().then(function(con){ console.log('connected!'); mysql = con; mysql.on('error', function (err, result) { console.log('error occurred. Reconneting...'.purple); mysqlAPI.reconnect(); }); mysql.query('SELECT 1 + 1 AS solution', function (err, results) { if(err) console.log('err',err); console.log('Works bro ',results); }); }); mysqlAPI.reconnect = function(){ mysqlCon.connect().then(function(con){ console.log("connected. getting new reference"); mysql = con; mysql.on('error', function (err, result) { mysqlAPI.reconnect(); }); }, function (error) { console.log("try again"); setTimeout(mysqlAPI.reconnect, 2000); }); };
我希望这有帮助。
不要在函数内部连接()和结束()。 这将导致重复调用该函数的问题。 只做连接
var connection = mysql.createConnection({ host: 'localhost', user: 'node', password: 'node', database: 'node_project' }) connection.connect(function(err) { if (err) throw err });
一次并重新使用该连接。
里面的function
function insertData(name,id) { connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) { if(err) throw err }); }