Atomic multi-query writes
An HTTP or edge handler needs several related statements to succeed or fail together.
Neon · Module
sql.transaction() executes multiple tagged SQL queries in one non-interactive transaction over the Neon serverless driver. Supply an array or a query-producing function, with optional transaction settings as the second argument.
sql.transaction() accepts an array of tagged SQL queries and executes them within one non-interactive transaction. It can also receive a function that returns an array of queries, while transaction-wide options are supplied as the second argument rather than attached to individual queries.
sql.transaction(queriesOrFn, options)| Name | Type | Description |
|---|---|---|
queriesOrFn | Query[] | (sql) => Query[] | An array of tagged SQL queries, or a non-async function receiving a query function and returning an array of queries. |
options | TransactionOptions | Optional query and transaction configuration, including arrayMode, fullResults, fetchOptions, isolationLevel, readOnly, and deferrable. |
The results of the queries, returned in the same order as the supplied queries.
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL!);
const [post, tag] = await sql.transaction([
sql`INSERT INTO posts (title) VALUES (${'Hello'}) RETURNING id`,
sql`INSERT INTO tags (name) VALUES (${'news'}) RETURNING id`
]);
console.log({ post, tag });Runs two SQL statements together as one non-interactive transaction.
An HTTP or edge handler needs several related statements to succeed or fail together.
A request needs a consistent group of reads without opening an interactive session.
A workload requires PostgreSQL isolation or read-only behavior.
sql.transaction() do?It executes multiple queries in one non-interactive transaction. The first argument can be an array of queries or a non-async function that receives a query function and returns an array.
Follow-up: When is HTTP unsuitable? Use the WebSocket-based Pool or Client for interactive transactions or session-oriented work.
The second argument contains transaction options. In addition to ordinary query options, it supports isolationLevel, readOnly, and deferrable.
Follow-up: What constraint applies to deferrable? It requires both readOnly: true and isolationLevel: 'Serializable'.
readOnly and deferrable work?readOnly: true requests a read-only transaction, and its documented default is false. deferrable: true requests a deferrable transaction, but only when the transaction is also read-only and serializable.
Follow-up: How should options be positioned? Supply them as the second argument to transaction(), not to the queries inside it.
neon()PoolClientarrayModefullResultsfetchOptionsisolationLevelreadOnly