【问题标题】:If I'm using a connection pool to run two separate queries, should I release my connection and connect again before the second query?如果我使用连接池运行两个单独的查询,我是否应该在第二个查询之前释放我的连接并再次连接?
【发布时间】:2016-04-14 13:34:41
【问题描述】:

我正在使用 PG npm module 来运行带有 node.js 和 PostgreSQL 的查询。我假设多个查询使用相同的连接而不释放它并在第二个查询之前再次获取它是最佳实践。对吧?

我对下面显示的示例代码感到困惑。从池中获取连接后,查询在回调中运行。如果我想使用相同的连接运行第二个查询怎么办?另一个回调?如何使用 Promise 库重写此代码以避免回调地狱?

var pg = require('pg');
var conString = "postgres://username:password@localhost/database";

//this initializes a connection pool 
//it will keep idle connections open for a (configurable) 30 seconds 
//and set a limit of 10 (also configurable) 
pg.connect(conString, function(err, client, done) {
  if(err) {
    return console.error('error fetching client from pool', err);
  }
  client.query('SELECT $1::int AS number', ['1'], function(err, result) {
    //call `done()` to release the client back to the pool 
    done();

    if(err) {
      return console.error('error running query', err);
    }
    console.log(result.rows[0].number);
    //output: 1 
  });
});

【问题讨论】:

  • 为了避免所有这些痛苦,您可以使用pg-promise,它会自动管理连接。
  • 老实说,我会遵循@vitaly-t 的建议。重新发明轮子没有意义。虽然他可能有点偏见,但这是他的模块和所有哈哈。杰克。这是一个受人尊敬的图书馆

标签: node.js postgresql


【解决方案1】:

一个天真的方法是这样的:

function runQuery(sql) {
  return new Promise((resolve, reject) => {
    const connectionString = `postgres://${db_config.USERNAME}:${db_config.PASSWORD}@${db_config.HOST}/${db_config.DATABASE}`;

    const client = new pg.Client(connectionString);

    client.connect(connectErr => {
      if (connectErr) {
        throw new Error(connectErr);
      }

      client.query(sql, (queryErr, result) => {
        if (queryErr) {
          return reject(new Error(queryErr));
        }

        client.end();

        return resolve(result);
      });
    });
  });
}

另一个可能更好的选择是利用模块为您排队查询的事实

database.js

const connectionString = `postgres://${db_config.USERNAME}:${db_config.PASSWORD}@${db_config.HOST}/${db_config.DATABASE}`;

const client = new pg.Client(connectionString);

client.connect(connectErr => {
  if (connectErr) {
    throw new Error(connectErr);
  }
});

module.exports.query = function runQuery(sql) {
    return new Promise(function(resolve, reject) {
    
      var query = client.query(sql);
    
      query.on('row', function(row, result) {
        result.addRow(row);
      });
    
      query.on('end', function(result) {
        resolve(result);
      });
      
      query.on('error', function(err) {
        reject(new Error(err));
      });
      
    });
  };

编辑:我做了一个快速编辑,使用作为第二个参数传递给row 事件的结果对象,而不是创建我自己的数组

【讨论】:

    猜你喜欢
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多