Kaizen
Browse modulesTenancyFunctions

Function: withTenantTransaction()

function withTenantTransaction<TTx extends RawExecutor, T>(
   client: PrismaClientLike<TTx>, 
   config: TenantTransactionConfig, 
   fn: (tx: TTx) => Promise<T>, 
   options?: {
  isolationLevel?: TransactionIsolationLevel;
}
): Promise<T>;

Defined in: server/tenancy/client.ts:246

Run fn in ONE interactive transaction with the tenant GUC pinned as the first statement (LOCAL, so it resets at COMMIT — pool-safe). This is the performant strategy from PLA-216: set the GUC once per request, not once per query. Reuses the persistence TransactionManager, so repositories resolving the ambient tx via getTx run inside this GUC-pinned transaction.

When unbound, the GUC is set empty ⇒ RLS fails closed. System/seed paths that legitimately span tenants must use the raw (un-registered) client instead.

ONE TENANT PER PHYSICAL TRANSACTION. The GUC is state on the shared Postgres transaction (TransactionManager.isInTransaction() / the interactive tx handle), not on a private ALS frame — so a nested call for a DIFFERENT tenant (sequential OR concurrent via Promise.all), including under a bare TransactionManager.startOrUseTransaction wrapper, can't switch it without racing sibling queries. Such a call therefore THROWS. Nesting with the SAME binding is fine (composition) — the GUC is already correct and isn't re-set. Cross-tenant work belongs in separate top-level transactions.

options.isolationLevel is forwarded to startOrUseTransaction — it applies only when this opens a NEW physical transaction and is ignored on the reuse path (the isolation level is fixed at BEGIN). Callers that need a stable snapshot across several reads (e.g. the insights executor's rows + totals) pass "RepeatableRead" here.

Type Parameters

Type Parameter
TTx extends RawExecutor
T

Parameters

ParameterType
clientPrismaClientLike<TTx>
configTenantTransactionConfig
fn(tx: TTx) => Promise<T>
options?{ isolationLevel?: TransactionIsolationLevel; }
options.isolationLevel?TransactionIsolationLevel

Returns

Promise<T>

On this page