Knex.js / SQL:Knex / SQL连接池

时间:2018-03-31 14:12:31

标签: javascript sql-server node.js knex.js

我对SQL连接池有疑问。我的团队正在我们的一个节点应用程序中使用knex.js库来进行数据库查询。 应用程序不时需要切换数据库。所以我的团队创建了一个初始化函数,它返回一个配置到正确数据库的knex对象。然后该对象用于执行所述查询。对我来说,这似乎是多余的,并且可能导致性能不佳,因为我们每次需要执行查询而不是重用单个knex对象时启动knex对象。我可以忽略,如果knex已经在你使用哪个数据库时这样做了(如果有人能够阐明这个问题,那就太棒了!)。而且,(这引出了我上面提到的问题)重新定义了连接池属性。那么这是否意味着我们每次都在创建新池,或者SQL(本例中为SQL Sever)是否重用已定义的连接池?问题可能不是特定于Knex,就像我使用像knex这样的库来进行C#,并以类似的方式调用该库,SQL Server是否知道不会创建更多的连接池?

示例代码:

/** db.js
 * @param {any} database 
 * @returns db: Knex
 */
module.exports = ( database ) => {
  var knex = require('knex')({
    client: 'mssql',
    connection: {
        database: database,
        server:  '127.0.0.1',
        user: 'your_database_user',
        password: 'your_database_password'
    },
    pool: {
        min: 0,
        max: 10,
        idleTimeoutMillis: 5000,
        softIdleTimeoutMillis: 2000,
        evictionRunIntervalMillis: 500
    }
  });
  return knex; 
}; 


Index.js

var db = require('./db.js'); 
/**
 * @returns users:Array
 */
const getUsers = async() => {
    const users = await db('master')
            .select()
            .from('users_table')
            .orderBy('user_id'); 
    return users; 
}

1 个答案:

答案 0 :(得分:2)

简答:节点require()语句的“单例”性质阻止了多次出现knex的重新初始化。因此,只要您不放弃db.变量引用,最初创建的池将继续用于进程的持续时间,而不是重新创建。

更多讨论......

  

...我的团队创建了一个返回knex的初始化函数   对象配置为正确的数据库。然后该对象习惯了   做查询。对我来说,这似乎是多余的,可能会造成不良   性能,因为我们每次都需要做一个knex对象   查询而不是重用单个knex对象。哪个我可以忽略   当您切换数据库时,knex已经这样做了......

    var db = require('./db.js');

node.js require语句创建一个单例对象。 (您可能已经知道)这意味着程序第一次使用require语句调用模块时,模块及其数据将被初始化,但连续相同的require调用将只重用相同的模块参考,不会重新初始化模块。

  

...重新定义了连接池属性。那意味着什么呢?   我们每次都在创建新的池,或者是SQL(SQL Sever   在这种情况下)重用已定义的连接池?

因此,由于require() - ed模块未重新初始化,因此不会重新创建最初创建的池。除非您放弃db变量引用(下面将详细讨论)。

  

问题可能不是Knex特定的,就像我使用了类似的库一样   knex用于C#,并以类似的方式调用该库,将SQL Server   知道不要建立更多的连接池吗?

一般来说,您需要构建或获取一些代码的连接,以便在流程的整个生命周期中正确管理连接池。 Knex和大多数其他数据库包装器为我们这样做。 (在Knex的封面下使用this library

在应用程序进程的整个生命周期中正确初始化然后使用单独初始化的池代码可以实现此目的。丢弃池并在您的过程中重新创建它会破坏池的目的。通常将池设置为进程初始化的一部分。

此外,这可能只是您问题中的错误陈述,但您的Node.js模块正在建立连接池,而不是SQL Server。

  

......应用程序不时需要切换数据库。我的   团队创建了一个返回knex对象的初始化函数   配置到正确的数据库。

从该声明中,我希望看到如下代码:

var db = require('./db.js');
var dbOther = require('./dbOther.js');

...每个都建立不同的数据库连接。如果你改为使用:

var db = require('./db.js');
// ... do other stuff here in the same module ...
var db = require('./dbOther.js');

...那么您可能会丢弃对第一个数据库的原始引用,在这种情况下,是的,您在切换连接时丢弃了数据库连接和连接池。

或者,您可以执行以下操作:

// initialize the 2 connection pools
const dbFirst = require('./db.js');
const dbOther = require('./dbOther.js');

// set the active connection
var db = dbFirst;
// change the active connection
db = dbOther;