繁体   English   中英

节点 mysqljs。 如何正确关闭连接

[英]Node mysqljs. How to properly close connections

我正在使用 mysqljs 通过 javascript 访问 MySQL。

我想指出,如果单个数据,这个过程似乎工作正常。 我在我的代码中输入了大量数据,作为批处理逐行处理。

我像这样创建我的连接:

var connection = mysql.createConnection({
    //debug: ['ComQueryPacket'],
    host        : dataSource.host,
    user        : dataSource.user,
    password: dataSource.password,
    database: dataSource.database
});

我有三个进行数据库查询的函数。

包含 SELECT 查询的函数是这样构建的:

dbSearch(data){
  var sql = "SELECT * from table where field =? and otherfield=?";
  return new Promise((resolve, reject) => {
    connection.query(sql, [data[0], data[1], (error, results, fields) => {
        if (error){
          console.log(error);
          reject("Database connection error: " + error);
         } else {
          resolve(results);
         }  
    });
  });
}

代码在另一个函数中执行:

if (dataItem){
  dbSearch(dataItem)
    .then((row) => {
        processingfunction(row);
    });

如果我省略 connection.end() 代码挂起并且数据流被阻止在正在处理的第一个项目。

如果我把 connection.end() 放在函数中,我会收到这个错误:

数据库连接错误:错误:调用退出后无法入队查询。

我把 connection.end() 作为代码的最后一行,一切正常

但问题在于更新和插入功能:

updateRecord(data){
  var sql = "UPDATE table set field=? where id=?";
  return new Promise((resolve, reject) => {
    connection.query(sql, [data[0], data[1], (error, results, fields) => {
     if (error){
      console.log(error);
      reject("Database connection error: " + error);
     } else {
      resolve(results);
     }
    });
  });
}

inputRecord(data){
  var sql = "INSERT INTO table (field1, field2, field3) VALUES(?,?,?)";
  return new Promise((resolve, reject) => {
    connection.query(sql, [data[0], data[1], data[2]], (error, results, fields) => {
      if (error){
        console.log(error);
        reject("Database connection error: " + error);
      } else {
        resolve(results);
      } 
    });
  });
}

在函数中使用 connection.end() 我得到这个错误。

Database connection error: Error: Cannot enqueue Query after invoking quit.
(node:40700) UnhandledPromiseRejectionWarning: Database connection error: Error: Cannot enqueue Query after invoking quit.
(node:40700) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:40700) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

根据文档,我不清楚如何正确处理关闭连接以便代码可以正确处理。

不知道我做错了什么。 可以从有使用连接处理数据块经验的人那里获得一些指导,以及如何正确处理关闭连接?

注意:当我尝试连接池时会发生类似的问题,因此这不是一个可行的解决方案。

您使用连接池,您不必手动关闭连接。 有一个.query()方便的方法。 由于您已经在使用.query() ,请不要在函数结束时关闭它。

这是 pool.getConnection() -> connection.query() -> connection.release() 代码流的快捷方式。

var mysql = require('mysql');
var pool  = mysql.createPool({
  connectionLimit : 10,
  host            : 'example.org',
  user            : 'bob',
  password        : 'secret',
  database        : 'my_db'
});

pool.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

您正在使用隐式连接。 意思是,您试图在没有先显式连接的情况下查询数据库。 这意味着每次运行此行时:

reject("Database connection error: " + error);

您不能确定这是连接错误。 可能是查询错误。 我相信明确地创建/破坏你的连接总是最好的。

inputRecord(data){
    var sql = "INSERT INTO table (field1, field2, field3) VALUES(?,?,?)";
    return new Promise((resolve, reject) => {
        connection.connect(function(err){
            if(err) reject("Database connection error: " + error);
            connection.query(sql, [data[0], data[1], data[2]], (error, results, fields) => {
                connection.end(); // Now you are certain a connection was made, and can be terminated
                if (error){
                    console.log(error);
                    reject("Database connection error: " + error);
                } else {
                    resolve(results);
                } 
            });
        });
    });
}

因为这是一个会反复使用的模式,我建议将它移到它自己的函数中:

executeQuery(query, params){
    return new Promise((resolve, reject) => {
        connection.connect(function(err){
            if(err) reject("Database connection error: " + error); // Connection error with certainty
            connection.query(query, params, (error, results, fields) => {
                connection.end(); // Now you are certain a connection was made, and can be terminated
                if (error){
                    console.log(error);
                    reject("Database query error: " + error);  // Query error
                } else {
                    resolve(results);
                } 
            });
        });
    });
}

然后简单地调用函数:

inputRecord(data){
    var sql = "INSERT INTO table (field1, field2, field3) VALUES(?,?,?)";
    return executeQuery(sql,[data[0],data[1],data[2]]);
}

updateRecord(data){
    var sql = "UPDATE table set field=? where id=?";
    return executeQuery(sql,[data[0],data[1]]);
}

dbSearch(data){
    var sql = "SELECT * from table where field =? and otherfield=?";
    return executeQuery(sql,[data[0],data[1]]);
}

要使用连接池,executeQuery 将变为:

executeQuery(query, params){
    return new Promise((resolve, reject) => {
        pool.query(query, params,function(err,res){ // shortcut for connect, query,end - no need to terminate the connection
            if(err) reject(err);
            else    resolve(res);
        });
    });
}

这应该可以解决您的问题,但如果没有,它至少应该通过打破错误条件并将所有与查询相关的代码放入同一函数来帮助缩小可能性。

首先检查连接

getConnection(){
   return new Promise((resolve, reject) => {
       if(connection.state === 'connected') resolve(connection);
       else {
            connection.connect(function(err) => {
                if(err) reject ("Connection error: " + error);
                else resolve(connection);
            });
       }
    });
 }

 executeQuery(query, params){

    return new Promise((resolve, reject) => {
        getConnection().then(connection =>{
            connection.query(query, params, (error, results, fields) => {
                connection.end(); // Now you are certain a connection was made, and can be terminated
                if (error){
                    console.log(error);
                    reject("Database query error: " + error);  // Query error
                } else {
                    resolve(results);
                } 
            });
        });
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM