Zaimplementowałem następujący kod:
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();
}
}
Tylko za pierwszym razem wszystko działa świetnie. Jeśli chcę „użyć” zapytania po raz drugi, pojawia się następujący błąd:
Cannot enqueue Handshake after invoking quit
Próbowałem nie .end()
podłączać, ale to nie pomogło.
Jak mogę rozwiązać ten problem?
connection.end
wewnątrzconnection.query
funkcji zwrotnej, ponieważ będzie wykonanie asynchronicznie.Odpowiedzi:
Jeśli używasz modułu node-mysql, po prostu usuń pliki .connect i .end. Właśnie sam rozwiązałem problem. Najwyraźniej w ostatniej iteracji wrzucili niepotrzebny kod, który również zawiera błędy. Nie musisz się łączyć, jeśli już uruchomiłeś wywołanie createConnection
źródło
Według:
Naprawianie węzła MySQL „Błąd: nie można umieścić w kolejce uzgadniania po wywołaniu wyjścia”:
http://codetheory.in/fixing-node-mysql-error-cannot-enqueue-handshake-after-invoking-quit/
i
Od:
Readme.md - serwer rozłącza się:
https://github.com/felixge/node-mysql#server-disconnects
To mówi:
Dostosowałem funkcję w taki sposób, że za każdym razem, gdy potrzebne jest połączenie, funkcja inicjalizująca automatycznie dodaje programy obsługi:
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; }
Inicjowanie połączenia:
var connection = initializeConnection({ host: "localhost", user: "user", password: "password" });
Drobna sugestia: może to nie dotyczyć wszystkich, ale napotkałem drobny problem dotyczący zakresu. Jeśli OP uzna, że ta zmiana była niepotrzebna, może ją usunąć. Dla mnie musiałem zmienić linię
initializeConnection
, która miałavar connection = mysql.createConnection(config);
po prostu po prostuPowodem jest to, że jeśli
connection
jest to zmienna globalna w twoim programie, to poprzedni problem polegał na tym, że tworzyłeś nowąconnection
zmienną podczas obsługi sygnału błędu. Ale w moim kodzie nodejs nadal używałem tej samejconnection
zmiennej globalnej do wykonywania zapytań, więc nowaconnection
byłaby utracona w lokalnym zakresieinitalizeConnection
metody. Ale w modyfikacji zapewnia, żeconnection
zmienna globalna zostanie zresetowana.Może to mieć znaczenie, jeśli występuje problem znany jakopo próbie wykonania zapytania po utracie połączenia, a następnie pomyślnym ponownym połączeniu. To mogła być literówka OP, ale chciałem tylko wyjaśnić.
źródło
Miałem ten sam problem i Google mnie tu zaprowadziło. Zgadzam się z @Ata, że nie można po prostu usunąć
end()
. Po dalszych Googlach myślę, że używaniepooling
jest lepszym sposobem.node-mysql doc o buforowaniu
To jest tak:
var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err, connection) { connection.query( 'bla bla', function(err, rows) { connection.release(); }); });
źródło
Nie łącz () i end () wewnątrz funkcji. Spowoduje to problemy z powtarzającymi się wywołaniami funkcji. Wykonaj tylko połączenie
var connection = mysql.createConnection({ host: 'localhost', user: 'node', password: 'node', database: 'node_project' }) connection.connect(function(err) { if (err) throw err });
raz i ponownie użyj tego połączenia.
Wewnątrz funkcji
function insertData(name,id) { connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) { if(err) throw err }); }
źródło
Funkcje AWS Lambda
W ten sposób nowe wywołania używają ustalonej puli, ale nie utrzymują działania funkcji. Mimo że nie uzyskujesz pełnej korzyści z puli (każde nowe połączenie używa nowego połączenia zamiast istniejącego), sprawia to, że drugie wywołanie może ustanowić nowe połączenie bez konieczności wcześniejszego zamykania poprzedniego.
Jeżeli chodzi o
connection.end()
Może to spowodować, że kolejne wywołanie zgłosi błąd. Wywołanie będzie nadal ponawiane później i będzie działać, ale z opóźnieniem.
Odnośnie
mysql.createPool()
doconnection.release()
Funkcja Lambda będzie działać do zaplanowanego limitu czasu, ponieważ nadal istnieje otwarte połączenie.
Przykład kodu
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(); }); }); };
źródło
w miejscu
connection.connect();
użytkowania -if(!connection._connectCalled ) { connection.connect(); }
jeśli jest już wywołana
connection._connectCalled =true
,& nie zostanie wykonana
connection.connect()
;uwaga - nie używaj
connection.end();
źródło
Myślę, że ten problem jest podobny do mojego:
Rozwiązałem ten problem, odtwarzając nowe połączenie za pomocą obietnic (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); }); };
Mam nadzieję, że to pomoże.
źródło
ROZWIĄZANIE: aby zapobiec temu błędowi (dla AWS LAMBDA):
Aby wyjść z „pętli zdarzeń Nodejs”, musisz zakończyć połączenie, a następnie połączyć się ponownie. Dodaj następny kod, aby wywołać wywołanie zwrotne:
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, }); });
źródło
Jeśli próbujesz uzyskać lambdę, okazało się, że kończenie programu obsługującego
context.done()
powoduje, że lambda kończy się. Przed dodaniem tej 1 linii po prostu działałby i działał, aż upłynął limit czasu.źródło
Możesz użyć debug: false,
Przykład: // połączenie mysql
var dbcon1 = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "node5", debug: false, });
źródło