stored query nodejs node example consultas conn mysql node.js node-mysql

query - nodejs mysql npm



Node.js MySQL necesita conexión persistente (3)

Necesito una conexión MySQL persistente para mi aplicación web Node. El problema es que esto sucede unas cuantas veces al día:

Error: Connection lost: The server closed the connection. at Protocol.end (/var/www/n/node_modules/mysql/lib/protocol/Protocol.js:73:13) at Socket.onend (stream.js:79:10) at Socket.EventEmitter.emit (events.js:117:20) at _stream_readable.js:895:16 at process._tickCallback (node.js:415:13) error: Forever detected script exited with code: 8 error: Forever restarting script for 2 time info: socket.io started

Aquí está mi código de conexión:

// Yes I know multipleStatements can be dangerous in the wrong hands. var sql = mysql.createConnection({ host: ''localhost'', user: ''my_username'', password: ''my_password'', database: ''my_database'', multipleStatements: true }); sql.connect(); 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); sql = mysql.createConnection(connection.config); handleDisconnect(sql); sql.connect(); }); } handleDisconnect(sql);

Como puede ver, el código de desconexión de la manija no funciona.


En respuesta a la pregunta @gladsocc :

¿Hay alguna forma de usar las piscinas sin refactorizar todo? Tengo docenas de consultas SQL en la aplicación.

Esto es lo que terminé construyendo. Es una envoltura para la función de consulta. Tomará la conexión, hará la consulta y luego liberará la conexión.

var pool = mysql.createPool(config.db); exports.connection = { query: function () { var queryArgs = Array.prototype.slice.call(arguments), events = [], eventNameIndex = {}; pool.getConnection(function (err, conn) { if (err) { if (eventNameIndex.error) { eventNameIndex.error(); } } if (conn) { var q = conn.query.apply(conn, queryArgs); q.on(''end'', function () { conn.release(); }); events.forEach(function (args) { q.on.apply(q, args); }); } }); return { on: function (eventName, callback) { events.push(Array.prototype.slice.call(arguments)); eventNameIndex[eventName] = callback; return this; } }; } };

Y lo uso como lo haría normalmente.

db.connection.query("SELECT * FROM `table` WHERE `id` = ? ", row_id) .on(''result'', function (row) { setData(row); }) .on(''error'', function (err) { callback({error: true, err: err}); });


Sé que esto está súper retrasado, pero escribí una solución para esto que creo que podría ser un poco más genérica y utilizable. Había escrito una aplicación completamente dependiente de connection.query() y cambiar a un grupo interrumpió esas llamadas.

Aquí está mi solución:

var mysql = require(''mysql''); var pool = mysql.createPool({ host : ''localhost'', user : ''user'', password : ''secret'', database : ''test'', port : 3306 }); module.exports = { query: function(){ var sql_args = []; var args = []; for(var i=0; i<arguments.length; i++){ args.push(arguments[i]); } var callback = args[args.length-1]; //last arg is callback pool.getConnection(function(err, connection) { if(err) { console.log(err); return callback(err); } if(args.length > 2){ sql_args = args[1]; } connection.query(args[0], sql_args, function(err, results) { connection.release(); // always put connection back in pool after last query if(err){ console.log(err); return callback(err); } callback(null, results); }); }); } };

Esto crea una instancia de la agrupación una vez, luego exporta un método llamado query . Ahora, cuando se llama a connection.query() cualquier lugar, llama a este método, que primero toma una conexión del grupo y luego pasa los argumentos a la conexión. Tiene el efecto adicional de capturar la devolución de llamada primero, por lo que puede devolver cualquier error al capturar una conexión del grupo.

Para usar esto, simplemente solicítelo como módulo en lugar de mysql. Ejemplo:

var connection = require(''../middleware/db''); function get_active_sessions(){ connection.query(''Select * from `sessions` where `Active`=1 and Expires>?;'', [~~(new Date()/1000)], function(err, results){ if(err){ console.log(err); } else{ console.log(results); } }); }

Esto se parece a la consulta normal, pero en realidad abre una agrupación y toma una conexión de la agrupación en segundo plano.


Utilice el grupo de conexión mysql. Se volverá a conectar cuando una conexión muere y obtendrá el beneficio adicional de poder realizar múltiples consultas de SQL al mismo tiempo. Si no usa el grupo de bases de datos, su aplicación bloqueará las solicitudes de la base de datos mientras espera a que finalicen las solicitudes actualmente en ejecución de la base de datos.

Generalmente defino un módulo de base de datos donde mantengo mis consultas separadas de mis rutas. Parece algo como esto ...

var mysql = require(''mysql''); var pool = mysql.createPool({ host : ''example.org'', user : ''bob'', password : ''secret'' }); exports.getUsers = function(callback) { pool.getConnection(function(err, connection) { if(err) { console.log(err); callback(true); return; } var sql = "SELECT id,name FROM users"; connection.query(sql, [], function(err, results) { connection.release(); // always put connection back in pool after last query if(err) { console.log(err); callback(true); return; } callback(false, results); }); }); });