关闭node.js中的postgres(pg)客户端连接

时间:2017-02-08 19:56:27

标签: javascript node.js postgresql pg

我有一个脚本,我想在节点中按计划运行。该脚本不会终止和退出。我怀疑这是因为我的数据库客户端仍处于打开状态。

var client = new pg.Client(conString);
client.connect();

function registerBundle (innerHash, outterHash) {
    // some stuff here
}

var query = client.query("SELECT id, chain FROM mytable where \
    state_ready = true and transaction_id='' ");

query.on('row', function(row) {
    var chain = row['chain'];
    var pg_record = row['id'];
    console.log(pg_record);
    var innerHash = "something";
    var outerHash = "something else";
    var registrar = registerBundle(innerHash, outerHash);

    var update = client.query('UPDATE mytable SET transaction_id = $1::text \
    where id=$2::int', [transactionHash, pg_record]);
    console.log(chain);
});

如果我包含以下内容,则客户端连接会在更新有时间之前关闭。

query.on('end', function() {
    client.end();
});

我无法使用setTimeout或任何其他此类机制,因为我不知道等待registerBundle函数完成需要多长时间。另外我认为query.on(' end'将在更新完成时触发。不确定如何测试。

我的问题是,我需要按顺序点火。

  • 查询数据库
  • 处理每一行(query.on
  • 使用registerBundle
  • 返回的值更新每一行
  • 处理完所有行后关闭数据库客户端/连接。
  • 终止脚本并退出节点

从python / php世界看起来很简单,但在我的javascript世界中崩溃了。

1 个答案:

答案 0 :(得分:1)

基于承诺的界面如pg-promise是可行的方法:

var bluebird = require('bluebird');
var pgp = require('pg-promise')({
    promiseLib: bluebird
});
var db = pgp(/*connection details*/);

db.tx(t => {
    // BEGIN executed
    return t.map('SELECT id, chain FROM mytable where state_ready = $1 and transaction_id = $2', [true, 123], a => {
        var chain = data.chain;
        var pg_record = data.id;
        return t.none('UPDATE mytable SET transaction_id = $1::text where id=$2::int', [transactionHash, pg_record]);
    }).then(t.batch); // settling all internal queries
})
    .then(data => {
        // success, COMMIT executed
    })
    .catch(error => {
        // error, ROLLBACK executed
    })
    .finally(pgp.end); // shuts down the connection pool

上面的示例完全符合您的要求,而且它使用了一个事务。但实际上,出于性能原因,您将希望在一个查询中完成所有操作;)

请参阅more examples