12

I'm running Node 7.6.0, which supports async/await. The node-postgres client pool supports async/await, and has a nice example here. However, the example for transactions in node-postgres (here) uses callbacks instead of async/await. Despite that example, I thought I'd try transactions with async/await in a quick test:

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!';

This seems to work just fine, but I was told by a node-postgres contributor that this is a bad idea. Unfortunately, he didn't take the time to explain why this is a bad idea—he just said to seek an answer on Stack Overflow.

Why is it a bad idea to perform transactions with async/await instead of callbacks in node-postgres?

1
  • 3
    It’s not a bad idea if you move the logic for creating a transaction into a different function, and vitaly-t just wants any excuse to promote his library. Ignore the comment. Commented Apr 11, 2017 at 19:59

2 Answers 2

14

The creator of node-postgres (brianc) graciously provided an excellent response to my original question on GitHub. The short answer is that it is not a bad idea to perform transactions with async/await.

See his full response here: https://github.com/brianc/node-postgres/issues/1252#issuecomment-293899088

Sign up to request clarification or add additional context in comments.

Comments

0

In addition to Rob Johansen's post I would like to share my TypeScript solution:

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 }

Usage:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.