Knex:超时获取连接。游泳池可能已满。你错过了.transacting(trx)电话吗?

时间:2016-11-05 06:08:16

标签: node.js knex.js

我使用以下代码建立knex连接,但经常发生错误

  

Knex:超时获取连接。游泳池可能已满。你错过了.transacting(trx)电话吗?

有人可以为这个问题建议解决方案吗?

var knexConn = reqKnex({
        client: pClient,
        native: false,
        connection: pConn,
        searchPath: pSearchPath,
        pool: {
            max: 7,
            min: 3,
            acquireTimeout: 60 * 1000
        }
    });


function getTransactionScope(pKnex, callback) {
    try {
        pKnex.transaction(function(trx) {
            return callback(trx);
        });
    } catch (error) {
        console.log(error);
    }
}

function ExecuteSQLQuery(pTranDB, pTrx, pQuery, pCallback) {
    try {
        var query = pTranDB.raw(pQuery);

        if (pTrx) {
            query = query.transacting(pTrx);
        }
        query.then(function(res, error) {
            try {
                if (error) {
                    console.log(error);
                } else {
                    return pCallback(res, error);
                }
            } catch (error) {
                console.log(error);
            }
        }).catch(function(error) {
            return pCallback(null, error);
        });
    } catch (error) {
        console.log(error);
    }
}

function Commit(pTrx, pIsCommit) {
    try {
        if (pIsCommit) {
            pTrx.commit();
        } else {
            pTrx.rollback();
        }
    } catch (error) {
        console.log(error);
    }
}

10 个答案:

答案 0 :(得分:16)

我用以下版本解决了这个问题:

"knex": "^0.21.1",
"objection": "^2.1.3",
"pg": "^8.0.3"

答案 1 :(得分:6)

我最近遇到了这个问题,我刚刚更新到Node v14.2.0

enter image description here

此版本对knex似乎有重大更改。幸运的是我有NVM,所以我切换到另一个版本(v12.16.3),这解决了问题。

enter image description here

祝你好运!

答案 2 :(得分:4)

当我升级到节点14.0.0时,我也遇到了这个问题。我恢复了节点版本,此问题消失了。

答案 3 :(得分:2)

在将stridi应用程序部署到heroku时,我遇到了同样的问题。 在我的package.json中,我具有以下版本:

  • "knex": "<0.20.0"
  • "pg": "^7.18.2"

我还具有以下节点引擎配置:

"engines": {
  "node": ">=10.0.0",
  "npm": ">=6.0.0"
},

将版本更改为<0.21.1^8.0.3(如此处建议的https://stackoverflow.com/a/61482183/4696783),并将节点引擎更改为12.16.x(如此处建议的https://stackoverflow.com/a/61942001/4696783)解决了这个问题。

答案 4 :(得分:2)

对于遇到此问题的其他人,这也可能是由于您的数据库主机名中的拼写错误造成的(我就是这种情况)。

答案 5 :(得分:0)

这将帮助您创建和破坏连接。

const config = {
    client: "pg",
    connection: {
      host: hostname,
      user: username,
      password: password,
      database: datbase
    },
    pool: {
      min: 0,
      max: 10
    },
    acquireConnectionTimeout: 1000
  }
  var Knex = require('knex')

  this.functioname = () => {
    var output = {}
    return new Promise(function (resolve) {
      var knex = new Knex(config)
      knex(tablename)
        .select()
        .then((result) => {
          if (result.length > 0) {
            output.error = false
            output.result = result
          } else {
            output.error = true
          }
          resolve(output)
        })
        .catch((err) => {
          err.error = true
          resolve(err)
        })
        .finally(() => {
          knex.destroy()
        })
    })
  }

答案 6 :(得分:0)

我有同样的问题, 考虑到: this post

  

应将属性propertyCreateError设置为false,以防止超时    获取连接。游泳池可能已满。您是否缺少.transacting(trx)通话?错误。

     

示例池配置:

     

“池”:{     “ min”:2     “最大值”:6     “ createTimeoutMillis”:3000,     “ acquireTimeoutMillis”:30000,     “ idleTimeoutMillis”:30000,     “ reapIntervalMillis”:1000,     “ createRetryIntervalMillis”:100,     “ propagateCreateError”:错误// <-默认为true,设置为false   },   说明:

     

在Knex中,默认情况下,propertyCreateError设置为true,如果与数据库的第一个创建连接失败,则会抛出TimeoutError,从而阻止tarn(连接池管理器)自动重新连接。

     

解决方案是将propertyCreateError设置为false,从而使knex在创建连接失败时自动重新连接,而不会引发错误。

this post

我已经进行了以下配置

module.exports = {
    client: 'pg',
    connection: {
        host: config.testDB.host,
        user: config.testDB.userName,
        port: config.testDB.port,
        password: config.testDB.password,
        database: 'testdb',
        charset: 'utf8'
    },
    pool: {
        max: 50,
        min: 2,
        // acquireTimeout: 60 * 1000,
        // createTimeoutMillis: 30000,
        // acquireTimeoutMillis: 30000,
        // idleTimeoutMillis: 30000,
        // reapIntervalMillis: 1000,
        // createRetryIntervalMillis: 100,
        propagateCreateError: false // <- default is true, set to false
    },
    migrations: {
        tableName: 'knex_migrations'
    }
}

如果它对您不起作用,请尝试将propertyError设置为true并取消注释

 "idleTimeoutMillis": 30000,
 "createTimeoutMillis": 30000,
 "acquireTimeoutMillis": 30000

答案 7 :(得分:0)

在我的申请中,我遇到了(中间的某个时间)

TimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?

我的 knex 配置是

const config = client: process.env.CLIENT,
  connection: {
    host: process.env.DBHOST,
    user: process.env.DBUSER,
    password: process.env.DBPASS,
    database: process.env.DATABASE
  },
  pool: { min: 0, max: 30, acquireTimeoutMillis: 60 * 1000 },
  seeds: {
    directory: './db/sds'
  },
  migrations: {
    directory: './db/mg'
  }
}

import knexLib from 'knex';
export const con = knexLib(config);

我正在使用它

import {con} from './con';
import {FormatError} from '../err'

const handler = (req)=>{
  const trx = con.transaction();
  try{
    const result = await con('insert-table').transacting(trx).insert(req.list).returning('*');
    const resultOfLog = await Promise.all(
      result.map((o) => {
        return con('log-table')
          .insert({event_id: 1, resource: o.id});
        })
    );
    return result;
  } catch(error){
    return new FormatError(error);
  }
}

答案 8 :(得分:0)

如果您在代理后面工作,则可能会发生此错误,因为您在命令行中的代理配置不正确。验证 envs http_proxy, https_proxy 情况下您的 SO 是 linux。

答案 9 :(得分:0)

属性propagateCreateError 应设置为false 以防止超时获取连接。游泳池可能已经满了。您是否错过了 .transacting(trx) 电话?错误。

示例池配置:

"pool": {
  "min": 2,
  "max": 6,
  "createTimeoutMillis": 3000,
  "acquireTimeoutMillis": 30000,
  "idleTimeoutMillis": 30000,
  "reapIntervalMillis": 1000,
  "createRetryIntervalMillis": 100,
  "propagateCreateError": false // <- default is true, set to false
},

说明propagateCreateError 在 Knex 中默认设置为 true 并在第一次创建数据库连接失败时抛出 TimeoutError,从而防止 tarn(连接池管理器)自动重新连接。

解决方案是将 propagateCreateError 设置为 false,从而使 knex 在创建连接失败时自动重新连接而不是抛出错误。

AuroraDB: 如果您连接到 AuroraDB 实例,当前它的启动时间很长,导致每次新的冷启动时都会出现 TimeoutError,要解决此问题,请设置 AWS Console -> RDS -> AuroraDB Instance -> Pause compute capacity after不活动分钟数:1440 小时,以防止数据库完全休眠。

详细解释请看 https://github.com/knex/knex/issues/2820