【问题标题】:Closing postgres (pg) client connection in node.js在 node.js 中关闭 postgres (pg) 客户端连接
【发布时间】:2017-06-26 14:54:17
【问题描述】:

我有一个脚本,我想在 node.js 中按计划运行。脚本没有终止和退出。我怀疑这是因为我的数据库客户端仍然打开。

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 世界中却分崩离析。

【问题讨论】:

    标签: javascript node.js postgresql pg


    【解决方案1】:

    pg-promise 这样的基于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

    【讨论】:

    • 在 SELECT 和 UPDATE 之间的某个地方我需要调用一个 javascript 函数来获取更新所需的值。我可以在 var pg_record 之后立即调用该函数吗?
    • 当我尝试执行此操作时,我发现一个错误“ReferenceError:数据未定义”。为了完成这项工作,我不得不将“a=> {”更改为“function(data) {”。不确定这是否正确。
    猜你喜欢
    • 1970-01-01
    • 2020-11-14
    • 2020-06-27
    • 2015-09-20
    • 1970-01-01
    • 2013-08-10
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多