【问题标题】:How to use Postgres pooling on NodeJS/Express server如何在 NodeJS/Express 服务器上使用 Postgres 池
【发布时间】:2019-08-19 16:22:24
【问题描述】:

Postgres 和一般事务池概念的新手。在文档中,Postgres 建议对单个查询使用 pool.query 方法,并警告“You must always return the client to the pool if you successfully check it out”。我的意思是,您必须为客户端调用 client.release() 或为池调用 pool.end() (如果我错了,请纠正我)。所以在我的 Node/Express 服务器中,我做了一个简单的测试:

const { Pool } = require('pg');
const pool = new Pool();

...

router.post('/test', async (req, res) => {
    let { username } = req.body;

    let dbRes;

    try{
        dbRes = await pool.query('SELECT * FROM users WHERE username = $1', [username]);
    } catch(err){
        let errMsg = "Error fetching user data: " + err;
        console.error(errMsg);
        return res.send({"actionSuccess": false, "error": errMsg});
    }

    //do something with dbRes, maybe do an update query;

    try{
        await pool.end();
    } catch(err){
        return "There was an error ending database pool: " + err.stack;
    }

    res.send({"dbRes": dbRes.rows[0]})
});

我运行服务器,使用 Postman 对该/test 路由进行后调用,一切正常。但是,如果我再次拨打相同的电话,这次我会收到错误 Error: Cannot use a pool after calling end on the pool。这是有道理的,我在这个请求中结束了池,但同时它没有意义。我猜池/客户端没有像我最初想象的那样绑定到单个服务器请求,这意味着如果对节点服务器的一个请求结束了池,它也会结束所有其他请求的池(如果我错了,请纠正我!我只是在这里猜测)。如果是这种情况,那么我永远不能调用 pool.end(),因为只要节点服务器正在运行,我想保持 tje 池打开/活动,对于其他服务器请求也是如此。这就引出了一个问题,我应该在哪里结束游泳池?可以永远打开它吗?这是否与文档中所述的整个 You must always return the client to the pool if you successfully check it out 规则相冲突?

【问题讨论】:

    标签: node.js postgresql express node-postgres


    【解决方案1】:

    如果您使用await pool.query 语法,则无需担心将连接释放回池。它为您处理关闭连接。在我看来,这是使用 pg pool 的正确方法。您可以/应该摆脱包含pool.end() 代码 sn-p 的第二个 try/catch 块。

    如果您使用老式的pool.connect 语法,则需要调用done() 将连接释放回池中。即

    pool.connect(function(err, client, done) {
        var sql = "SELECT * FROM users WHERE username = $1";
        var values = [username];
    
        client.query(sql, values, function(err, result) {
            done(); // releases connection back to the pool        
            // Handle results
        });
    });
    

    【讨论】:

    • 所以我只需要担心如果我使用的是pg.Client而不是pg.Pool那么释放连接吗?
    • 仅当您使用pool.connectpool.query 为您执行 pool.connectclient.querydone() 步骤,以便在完成 pool.connect 呼叫后为您关闭连接。
    猜你喜欢
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 2017-06-07
    • 2017-06-13
    • 1970-01-01
    相关资源
    最近更新 更多