簡體   English   中英

如何解決 nodejs uncaughtException: Connection already Release 錯誤和 MaxListenersExceededWarning?

[英]How to solve nodejs uncaughtException: Connection already released error and MaxListenersExceededWarning?

我正在構建一個快速服務器以從我的 React 前端接收請求(一個包含 10 個項目的字典),然后將數據保存到數據庫中。 下面是我的代碼。 我發現我的代碼可以正常工作,並且查詢確實將記錄保存回 Db。 但是在每個 for 循環中,這個錯誤都會在 server.js 中返回。 是什么導致此錯誤和 MaxListenersExceededWarning?

The request data: 
{{.....}, {.....}, {.....}, {.....}, {.....}} #10 item

Code:
connection.js:
const p = mysql.createPool({
  "connectionLimit" : 100,
  "host": "example.org",
  "user": "test",
  "password": "test",
  "database": "test",
  "multipleStatements": true
});

const getConnection = function(callback) {
    p.getConnection(function(err, connection) {
        callback(err, connection)
    })
};

module.exports = getConnection

routers.js
router.post('/test', (req, res) => {
    getConnection(function(err, conn){
        if (err) {
            return res.json({ success: false, error: err })
        } else {
          const dict = req.body;
          Object.keys(dict).forEach(function(r){
              #putting dict's value to query 
              query = "UPDATE ......;"
              conn.query(query, function (err, result, fields) {
                conn.release()
                console.log(query)
                  if (err) {
                      console.log("err")
                      return res.json({ success: false, error: err });
                  }
              });
            });
          }
        });
        return res.json({ success: true });
    });

Error:
error: uncaughtException: Connection already released
Error: Connection already released
    at Pool.releaseConnection (/home/node_modules/mysql/lib/Pool.js:138:13)
    at PoolConnection.release (/home/node_modules/mysql/lib/PoolConnection.js:35:15)
    at Query.<anonymous> (/home/routes/test.js:276:22)
    at Query.<anonymous> (/home/node_modules/mysql/lib/Connection.js:526:10)
    at Query._callback (/home/node_modules/mysql/lib/Connection.js:488:16)
    at Query.Sequence.end (/home/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Query._handleFinalResultPacket (/home//node_modules/mysql/lib/protocol/sequences/Query.js:149:8)
    at Query.OkPacket (/home//node_modules/mysql/lib/protocol/sequences/Query.js:74:10)
    at Protocol._parsePacket (/home//node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/home//node_modules/mysql/lib/protocol/Parser.js:433:10)
(node:15881) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 finish listeners added. Use emitter.setMaxListeners() to increase limit

正在從池中檢索一個連接 ( conn ),並用於在forEach循環中啟動 10 個查詢。

當第一個查詢完成運行時,其回調的第一步是: conn.release() 連接被釋放。

當第二個查詢完成運行時,其回調也嘗試釋放連接,從而導致錯誤。

這個問題可以通過多種方式解決:

使用計數器求解

在數據庫查詢的回調中,在調用call.release之前,檢查已經處理的查詢數,只有在處理完最后一個產品時才關閉連接。

      const dict = req.body;

      // initialize counter
      let itemCount = 0
          , errors = []

      Object.keys(dict).forEach(function(r){
          #putting dict's value to query 
          query = "UPDATE ......;"
          conn.query(query, function (err, result, fields) {


            // check whether this is the last callback
            if (itemCount === dict.length-1) {
                conn.release()

                let result = errors.length ? { success: false, error: errors } : { success: true }

                res.json(result)

            }

            // increment counter
            itemCount++

            console.log(query)
              if (err) {
                  console.log("err")
                  errors.push(err)
              }
          });
        });

編輯res.json調用也有一個問題:在問題的代碼中, res.json({ success: true })總是被執行,而不等待查詢的執行結果。 上面修改的代碼示例在所有查詢執行后只調用res.json一次,這是唯一應該調用res.json地方。 這意味着修改客戶端代碼,以便它可以處理一系列錯誤,而不僅僅是一個錯誤。

通過使用遞歸函數而不是 for 循環來解決。

使用for循環來執行異步代碼不是一個好習慣。 每當數據量變得太大時,您可能會遇到Maximum call stack size exceeded錯誤。

相反,創建一個遞歸函數(例如updateDictItem )以一次處理一個更新查詢。 本文中閱讀有關 node.js 中異步模式的更多信息。

其他可能的改進

與其觸發十個數據庫查詢,不如考慮將所有更新分組在一個MERGE更新語句中,否則在TRANSACTION進行所有更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM