何时断开连接以及何时结束 pg 客户端或池

新手上路,请多包涵

我的堆栈是 node、express 和 pg 模块。我真的试图通过文档和一些过时的教程来理解。 我不知道何时以及如何断开和结束客户端。

对于某些路线,我决定使用游泳池。这是我的代码

const pool = new pg.Pool({
  user: 'pooluser',host: 'localhost',database: 'mydb',password: 'pooluser',port: 5432});

pool.on('error', (err, client) => {
  console.log('error ', err);  process.exit(-1);
});

app.get('/', (req, res)=>{
  pool.connect()
    .then(client => {
      return client.query('select ....')
            .then(resolved => {
              client.release();
              console.log(resolved.rows);
            })
            .catch(e => {
              client.release();
              console.log('error', e);
            })
      pool.end();
    })
});

在 CMS 的路由中,我使用客户端而不是具有与池不同的数据库权限的池。

 const client = new pg.Client({
  user: 'clientuser',host: 'localhost',database: 'mydb',password: 'clientuser',port: 5432});
client.connect();

const signup = (user) => {
  return new Promise((resolved, rejeted)=>{
    getUser(user.email)
    .then(getUserRes => {
      if (!getUserRes) {
        return resolved(false);
      }
            client.query('insert into user(username, password) values ($1,$2)',[user.username,user.password])
              .then(queryRes => {
                client.end();
                resolved(true);
              })
              .catch(queryError => {
                client.end();
                rejeted('username already used');
              });
    })
    .catch(getUserError => {
      return rejeted('error');
    });
  })
};

const getUser = (username) => {
  return new Promise((resolved, rejeted)=>{
    client.query('select username from user WHERE username= $1',[username])
      .then(res => {
        client.end();
        if (res.rows.length == 0) {
          return resolved(true);
        }
        resolved(false);
      })
      .catch(e => {
        client.end();
        console.error('error ', e);
      });
  })
}

在这种情况下,如果我得到一个 username already used 并尝试使用另一个用户名重新发布,则 getUser 的查询永远不会启动并且页面挂起。如果我从这两个函数中删除 client.end(); ,它将起作用。

我很困惑,所以请就如何以及何时断开连接以及完全结束池或客户端提供建议。任何提示或解释或教程将不胜感激。

谢谢

原文由 slevin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 699
2 个回答

首先,来自 pg 文档*:

 const { Pool } = require('pg')

const pool = new Pool()

// the pool with emit an error on behalf of any idle clients
// it contains if a backend error or network partition happens
pool.on('error', (err, client) => {
  console.error('Unexpected error on idle client', err) // your callback here
  process.exit(-1)
})

// promise - checkout a client
pool.connect()
  .then(client => {
    return client.query('SELECT * FROM users WHERE id = $1', [1]) // your query string here
      .then(res => {
        client.release()
        console.log(res.rows[0]) // your callback here
      })
      .catch(e => {
        client.release()
        console.log(err.stack) // your callback here
      })
  })

这个代码/结构足以让你的 池子 工作,在 这里提供你的 东西。如果你关闭你的应用程序,连接将正常挂起,因为池创建得很好,完全不会挂起,即使它确实提供了手动挂起的方式,请参阅 文章 的最后一节。另请查看前面的红色部分,上面写着“您必须始终返回客户……”以接受

  • 强制 client.release() 指令
  • 在访问论点之前。
  • 您在回调中范围/关闭客户端。

然后,来自 pg.client 文档*:

带有承诺的纯文本查询

const { Client } = require('pg').Client
const client = new Client()
client.connect()
client.query('SELECT NOW()') // your query string here
  .then(result => console.log(result)) // your callback here
  .catch(e => console.error(e.stack)) // your callback here
  .then(() => client.end())

在我看来,最清晰的语法:

  • 无论结果如何,您都会结束客户端。
  • 您在 结束 客户端之前访问结果。
  • 您不会在回调中限定/关闭客户端

乍一看,这两种语法之间的这种对立可能会让人感到困惑,但其中并没有什么神奇之处,它是实现构造语法。专注于 您的 回调和查询,而不是那些结构,只需挑选最适合您的眼睛并将 其与您的 代码一起提供。

*为了清楚起见,我 在此处添加了评论//您的 xxx

原文由 lucchi 发布,翻译遵循 CC BY-SA 4.0 许可协议

node-postgres 的 github 上 的文档说:

专家提示:除非你需要运行一个事务(这需要一个客户端进行多个查询)或者你有一些其他的边缘情况,比如流式传输行或使用游标,你应该几乎总是只使用 pool.query。它很简单,它做正确的事 ™️,并且永远不会忘记在查询完成后将客户端返回到池中。

所以对于非事务查询,调用下面的代码就足够了。

 var pool = new Pool()

pool.query('select username from user WHERE username= $1',[username], function(err, res) {

  console.log(res.rows[0].username)

})

通过使用 pool.query ,库将负责在查询完成后释放客户端。

原文由 milhamj 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题