Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Neon · Module

sql.transaction

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.

How it works

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.

Syntax

sql.transaction(queriesOrFn, options)

Parameters

NameTypeDescription
queriesOrFnQuery[] | (sql) => Query[]An array of tagged SQL queries, or a non-async function receiving a query function and returning an array of queries.
optionsTransactionOptionsOptional query and transaction configuration, including arrayMode, fullResults, fetchOptions, isolationLevel, readOnly, and deferrable.

Returns

The results of the queries, returned in the same order as the supplied queries.

Key points

  • Use the function when several statements must be grouped into one HTTP-based transaction.
  • The API accepts either a query array or a function that produces one.
  • The second argument carries regular query options as well as transaction settings.
  • Transaction behavior can be configured with isolation level, read-only mode, and deferrability.
  • Setting read-only mode prevents the transaction from being used for writes.
  • Deferrability is conditional on serializable isolation together with read-only mode.

Common mistakes

  • Place options on the transaction call itself; options embedded in its individual queries are not the documented configuration mechanism.
  • The isolation-level value is restricted to the four documented PostgreSQL isolation modes.

Example: Execute multiple queries atomically

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.

When to use it

Atomic multi-query writes

An HTTP or edge handler needs several related statements to succeed or fail together.

Grouped read operations

A request needs a consistent group of reads without opening an interactive session.

Transaction policy configuration

A workload requires PostgreSQL isolation or read-only behavior.

Interview questions

QWhat does 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.

QWhich transaction-specific options are available?

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'.

QHow do 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()
  • Pool
  • Client
  • arrayMode
  • fullResults
  • fetchOptions
  • isolationLevel
  • readOnly

Source: Neon serverless driver. Checked 2026-10-16.