使用回调或async / await的node-postgres事务?

时间:2017-04-11 16:11:39

标签: node.js postgresql transactions node-postgres

我正在运行Node 7.6.0,它支持async / await。 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由节点postgres贡献者认为这是一个坏主意。不幸的是,他没有花时间解释为什么这是一个坏主意 - 他只是想在Stack Overflow上寻求答案。

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

2 个答案:

答案 0 :(得分:7)

node-postgres的创建者(brianc)慷慨地回答了我在GitHub上的原始问题。简短的回答是,使用async/await执行交易

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

答案 1 :(得分:0)

除了 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;
});