簡體   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