【问题标题】:node-postgres transactions with callbacks or async/await?带有回调或异步/等待的 node-postgres 事务?
【发布时间】:2021-01-06 08:59:02
【问题描述】:

我正在运行支持异步/等待的 Node 7.6.0。 node-postgres 客户端池支持 async/await,并且有一个很好的示例 here。但是,node-postgres (here) 中的事务示例使用回调而不是 async/await。尽管有这个例子,我还是想在快速测试中尝试使用 async/await 进行事务:

let client = null;

try {
    client = await this.pool.connect();
} catch (error) {
    console.log('A client pool error occurred:', error);
    return error;
}

try {
    await client.query('BEGIN');
    await client.query('UPDATE foo SET bar = 1');
    await client.query('UPDATE bar SET foo = 2');
    await client.query('COMMIT');
} catch (error) {
    try {
        await client.query('ROLLBACK');
    } catch (rollbackError) {
        console.log('A rollback error occurred:', rollbackError);
    }
    console.log('An error occurred:', error);
    return error;
} finally {
    client.release();
}

return 'Success!';

这似乎工作得很好,但 I was told 由 node-postgres 贡献者认为这是一个坏主意。不幸的是,他没有花时间解释为什么这是一个坏主意——他只是说要在 Stack Overflow 上寻求答案。

为什么在 node-postgres 中使用 async/await 而不是回调来执行事务是个坏主意?

【问题讨论】:

  • 如果你将创建事务的逻辑移到不同的函数中,这不是一个坏主意,vitally-t 只是想找个借口来推广他的库。忽略评论。

标签: node.js postgresql transactions node-postgres


【解决方案1】:

node-postgres 的创建者 (brianc) 慷慨地对我在 GitHub 上的原始问题做出了出色的回答。简短的回答是不是使用async/await 执行交易是一个坏主意。

在此处查看他的完整回复:https://github.com/brianc/node-postgres/issues/1252#issuecomment-293899088

【讨论】:

    【解决方案2】:

    除了 Rob Johansen 的帖子,我想分享我的 TypeScript 解决方案:

    import { PoolClient } from "pg"
    import { pool } from "../database"
    
    const tx = async (callback: (client: PoolClient) => void) => {
      const client = await pool.connect();
    
      try {
        await client.query('BEGIN')
        try {
          await callback(client)
          await client.query('COMMIT')
        } catch (e) {
          await client.query('ROLLBACK')
        }
      } finally {
        client.release()
      }
    }
    
    export { tx }
    

    用法:

    let result;
    
    await tx(async client => {
      const { rows } = await client.query<{ cnt: string }>('SELECT COUNT(*) AS cnt FROM users WHERE username = $1', [username]);
      result = parseInt(rows[0].cnt) > 0;
    });
    

    【讨论】:

      猜你喜欢
      • 2017-03-31
      • 2021-06-30
      • 2017-03-13
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 1970-01-01
      • 2022-11-01
      相关资源
      最近更新 更多