何时何地使用knex.destroy?

时间:2019-04-22 15:14:07

标签: javascript node.js knex.js

我对在Node API中在何处使用knex.destroy()感到困惑。

如果我在打开连接进行通话后不使用knex.destroy(),则连接池会随着时间的推移而填满,从而导致错误:

  

未处理的拒绝TimeoutError:Knex:超时获取连接。游泳池可能已满。您是否错过了.transacting(trx)通话?

如果我关闭连接,这对我来说很有意义,

router.get('/users', function(req, res, next) {
    var select = knex.select('*').from('users');
    select.then((result) => {
        res.send(result);
    }).catch((error) => {
        res.send(error);
    }).finally(function() {
        knex.destroy(); // close it when I'm done
    });
});

对于单独的API调用,连接已关闭:

  

未处理的拒绝错误:无法获取连接       在Client_PG.acquireConnection(/var/app/current/node_modules/knex/lib/client.js:331:40)

那么我实际上在哪里和何时破坏连接?同样,此Node应用程序仅充当API。每个API调用都应该打开然后关闭连接,但是knex似乎不喜欢这样。


需要knex的路由器文件:(我对每个路由器文件都这样做)

const knexService = require('../knexService');
const bookshelf = knexService.bookshelf;
const knex = knexService.knex;
let User = require('../models/User');

module.exports = function(app, router) {
   router.get('/users', function(req, res, next) {
       var select = knex.select('*').from('users');
       select.then((result) => {
           res.send(result);
       }).catch((error) => {
           res.send(error);
       }).finally(function() {
           knex.destroy(); // close it when I'm done
       });
   });
   ...

UserModel文件

const knexService = require('../knexService');
const bookshelf = knexService.bookshelf;
var BaseModel = require('./BaseModel');
var addressModel = require('./Address').Address;

var User = BaseModel.extend({
    tableName: 'users',
    hasTimestamps: true,
    addresses: function() {
        return this.hasMany(addressModel);
    }
});

KnexService.js

const knexfile = require('./knexfile');
const knex = require('knex')(knexfile.production);
const bookshelf = require('bookshelf')(knex);

module.exports.knex = knex;
module.exports.bookshelf = bookshelf;

KnexFile.js

module.exports = {

    development: {
        client: 'pg',
        version: '7.2',
        connection: {
            ...

1 个答案:

答案 0 :(得分:3)

knex.destroy()应该在您希望通过knex丢弃池中的所有连接并停止所有计时器等时调用,以便应用程序可以正常结束。

因此,基本上,只有在应用程序退出时才应调用它,除非您正在做一些更复杂的事情,例如,使用多个knex实例连接到多个数据库。

如果连接用完了,并且池已满,则说明您的代码有问题。可能的原因可能是:

  • 同时进行太多持久查询
  • 创建事务并且从不提交/回退,因此这些连接永远不会返回到池中
  • 在knex /书架/一些中间件中的错误

您应该尝试查明应用程序的哪些部分导致池被填满,删除所有与bookshelf相关的代码,并找到可用于复制问题的最小设置(还删除所有事务开始)。

您是真的在使用PostgreSQL 7.2还是要连接一些与PostgreSQL兼容的自定义数据库?这可能会引起一些问题,但是我认为这些问题不会以这种方式暴露出来,而是将断开的连接留在了池中。