Ich habe den folgenden Code implementiert:
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();
}
}
Alles funktioniert nur zum ersten Mal großartig. Wenn ich die Abfrage zum zweiten Mal "verwenden" möchte, wird folgende Fehlermeldung angezeigt:
Cannot enqueue Handshake after invoking quit
Ich habe versucht, keine .end()
Verbindungen herzustellen, aber es hat nicht geholfen.
Wie kann ich dieses Problem beheben?
connection.end
innerhalb derconnection.query
Rückruffunktion, da diese asynchron ausgeführt wird.Antworten:
Wenn Sie das Node-MySQL-Modul verwenden, entfernen Sie einfach .connect und .end. Habe das Problem einfach selbst gelöst. Anscheinend haben sie in ihrer letzten Iteration unnötigen Code eingegeben, der ebenfalls fehlerhaft ist. Sie müssen keine Verbindung herstellen, wenn Sie den Aufruf createConnection bereits ausgeführt haben
quelle
Gemäß:
Fixing Node Mysql "Fehler: Handshake kann nach Aufrufen von quit nicht in die Warteschlange gestellt werden.":
http://codetheory.in/fixing-node-mysql-error-cannot-enqueue-handshake-after-invoking-quit/
und
Von:
Readme.md - Server trennt:
https://github.com/felixge/node-mysql#server-disconnects
Es sagt:
Ich habe die Funktion so angepasst, dass jedes Mal, wenn eine Verbindung benötigt wird, eine Initialisierungsfunktion die Handler automatisch hinzufügt:
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; }
Verbindung initialisieren:
var connection = initializeConnection({ host: "localhost", user: "user", password: "password" });
Kleiner Vorschlag: Dies gilt möglicherweise nicht für alle, aber ich bin auf ein kleines Problem im Zusammenhang mit dem Umfang gestoßen. Wenn das OP der Ansicht ist, dass diese Bearbeitung nicht erforderlich war, kann er sie entfernen. Für mich musste ich eine Zeile ändern
initializeConnection
, dievar connection = mysql.createConnection(config);
einfach nur warDer Grund dafür ist, dass wenn
connection
es sich um eine globale Variable in Ihrem Programm handelt, das Problem zuvor darin bestand, dass Sieconnection
beim Behandeln eines Fehlersignals eine neue Variable erstellt haben. In meinem nodejs-Code habe ich jedoch weiterhin dieselbe globaleconnection
Variable zum Ausführen von Abfragen verwendet, sodass die neue Variableconnection
im lokalen Bereich derinitalizeConnection
Methode verloren geht. Bei der Änderung wird jedoch sichergestellt, dass die globaleconnection
Variable zurückgesetzt wird. Dies kann relevant sein, wenn ein Problem auftritt, das als bekannt istnach dem Versuch, eine Abfrage durchzuführen, nachdem die Verbindung unterbrochen und die Verbindung erfolgreich wiederhergestellt wurde. Dies mag ein Tippfehler des OP gewesen sein, aber ich wollte es nur klarstellen.
quelle
Ich hatte das gleiche Problem und Google führte mich hierher. Ich stimme @Ata zu, dass es nicht richtig ist, nur zu entfernen
end()
. Nach weiterem Googeln denke ich, dass die Verwendungpooling
ein besserer Weg ist.Node-MySQL-Dokument zum Pooling
Es ist so:
var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err, connection) { connection.query( 'bla bla', function(err, rows) { connection.release(); }); });
quelle
Verbinden Sie () und end () nicht innerhalb der Funktion. Dies führt bei wiederholten Aufrufen der Funktion zu Problemen. Stellen Sie nur die Verbindung her
var connection = mysql.createConnection({ host: 'localhost', user: 'node', password: 'node', database: 'node_project' }) connection.connect(function(err) { if (err) throw err });
einmal und verwenden Sie diese Verbindung wieder.
Innerhalb der Funktion
function insertData(name,id) { connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) { if(err) throw err }); }
quelle
AWS Lambda funktioniert
Auf diese Weise verwenden neue Aufrufe den eingerichteten Pool, lassen die Funktion jedoch nicht laufen. Obwohl Sie nicht den vollen Nutzen aus dem Pooling ziehen können (jede neue Verbindung verwendet eine neue Verbindung anstelle einer vorhandenen), kann ein zweiter Aufruf eine neue Verbindung herstellen, ohne dass die vorherige Verbindung zuerst geschlossen werden muss.
Bezüglich
connection.end()
Dies kann dazu führen, dass ein nachfolgender Aufruf einen Fehler auslöst. Der Aufruf wird später noch wiederholt und funktioniert, jedoch mit Verzögerung.
In Bezug
mysql.createPool()
aufconnection.release()
Die Lambda-Funktion wird bis zum geplanten Zeitlimit weiter ausgeführt, da noch eine offene Verbindung besteht.
Codebeispiel
const mysql = require('mysql'); const pool = mysql.createPool({ connectionLimit: 100, host: process.env.DATABASE_HOST, user: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, }); exports.handler = (event) => { pool.getConnection((error, connection) => { if (error) throw error; connection.query(` INSERT INTO table_name (event) VALUES ('${event}') `, function(error, results, fields) { if (error) throw error; connection.destroy(); }); }); };
quelle
anstelle der
connection.connect();
Verwendung -if(!connection._connectCalled ) { connection.connect(); }
Wenn es dann bereits aufgerufen wird
connection._connectCalled =true
, wird& nicht ausgeführt
connection.connect()
.Hinweis - nicht verwenden
connection.end();
quelle
Ich denke, dieses Problem ähnelt meinem:
Ich habe dieses Problem gelöst, indem ich eine neue Verbindung mit der Verwendung von Versprechungen wiederhergestellt habe (q).
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); }); };
Ich hoffe das hilft.
quelle
LÖSUNG: Um diesen Fehler zu vermeiden (für AWS LAMBDA):
Um die "Nodejs-Ereignisschleife" zu beenden, müssen Sie die Verbindung beenden und die Verbindung erneut herstellen. Fügen Sie den nächsten Code hinzu, um den Rückruf aufzurufen:
connection.end( function(err) { if (err) {console.log("Error ending the connection:",err);} // reconnect in order to prevent the"Cannot enqueue Handshake after invoking quit" connection = mysql.createConnection({ host : 'rds.host', port : 3306, user : 'user', password : 'password', database : 'target database' }); callback(null, { statusCode: 200, body: response, }); });
quelle
Wenn Sie versuchen, ein Lambda zu bekommen, habe ich festgestellt, dass das Beenden des Handlers mit
context.done()
dem Lambda beendet werden muss. Bevor diese 1 Zeile hinzugefügt wird, wird sie nur ausgeführt und ausgeführt, bis das Zeitlimit abgelaufen ist.quelle
Sie können debug verwenden: false,
Beispiel: // MySQL-Verbindung
var dbcon1 = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "node5", debug: false, });
quelle