Rolf B: Problem mit node.js und promise-mysql

Beitrag lesen

Hallo J o,

dsa Problem ist: Wenn mehrere Connections parallel laufen, wird die Connection-Variable überschrieben. D.h. die zuerst dort abgelegte Connection wird nicht released, dafür die zuletzt abgelegte Connection aber mehrfach.

Sofern man nicht mehrere Queries auf einer Connection hintereinander ausführen will, ist da aber alles kein Problem. Man kann die Connection mit .release() freigeben

Die Lösung ist, das Ganze in eine function zu packen, damit connection nicht global ist sondern in einer Closure liegt. Mein Konzept - was ich aber nicht testen kann weil ich kein node mit SQL habe - wäre, dass diese function sich NUR um das Handling der Connection kümmert und ein bisschen Error-Logging macht. Ansonsten sollte sie ein Promise zurückgeben, mit dem die Fachliche Weiterverarbeitung erfolgt.

Wenn man auf einer Connection unbedingt mehr als eine Query ausführen will, dann wird die Sache komplexer, aber bei Verwendung des Pools besteht dieser Bedarf eigentlich nicht.

// An der Stelle wo der SQL Befehl abgesetzt werden muss
sqlQuery("update tabelle set wert = 1")
.then(function(rows) {
   if (rows.changedRows == 1) {
      consolelog("update successful");
   } else {
      consolelog('error occurred!');
   }
})
.catch(function(err) { });

// -----

// somewhere else
function sqlQuery(strQuery) {
   let connection;
   return pool.getConnection()           // Das letzte Promise der Kette zurückgeben!
          .then(function(conn)
          {
             let connection = conn;
             return conn.query(strQuery);
          })
          .then(function(rows)
          {
             connection.release();
             return rows;                // Query-Result durchreichen
          })
          .catch(function(error)
          {
			       connection.release();
             // logs out the error
             consolelog("Fehler bei: "+strQuery);
			       consolelog(error);
             throw error;                // throw, damit .catch() beim Aufrufer greift
      		})
}

Die mysql-Doku ist unklar, ob connection.release() direkt nach .query abgesetzt werden darf oder nicht. Bei dem .end() Aufruf bei ungepoolten Queries DARF man das. Das müsste man ausprobieren - damit würde man sich eine .then-Stufe sparen können.

Unter Verwendung eines .finally-Handlers kann man die ganze Sache noch zusammenfassen, aber das muss unter node.js nicht funktionieren, ich kann es nicht testen.

function sqlQuery(strQuery) {
   let connection;
   return pool.getConnection()           // Das letzte Promise der Kette zurückgeben!
          .then(function(conn)
          {
             let connection = conn;
             return conn.query(strQuery);
          })
          .catch(function(error)
          {
             // logs out the error
             consolelog("Fehler bei: "+strQuery);
			       consolelog(error);
             throw error;                // throw, damit .catch() beim Aufrufer greift
      		})
          .finally(function() {
             connection.release();
          });
}

Rolf

--
sumpsi - posui - clusi