BEGIN TRANSACTION — all-or-nothing blocks

View .md

Turn a script into one all-or-nothing native transaction. The editor validates every rule at the keystroke — where DynamoDB would report an opaque cancellation after the run, the studio catches violations before the wire. Write blocks use a deliberate two-step run (first Run previews the plan, an unchanged second Run commits) and carry an idempotency token, so a retry is a no-op rather than a double-apply.

Syntax

sql
BEGIN TRANSACTION;statement;            -- writes only, or reads only — never mixedstatement;            -- each write targets ONE item by its full key…                     -- up to 100 statements, each item at most onceCOMMIT;

Extra WHERE conditions compile to an atomic ConditionExpression; arithmetic SET compiles to a native UpdateExpression; anything the native form can't express identically is an honest refusal naming the fix, never a silent drop. Clock functions share one instant across the block. Guide: Writes & transactions.

Use cases

Move money with a balance guard Native

Debit, credit, and ledger row land together or not at all — and the balance >= 100 predicate becomes a native condition, so an uncovered debit cancels the whole block.

sql
BEGIN TRANSACTION;UPDATE "stage.Accounts" SET balance = balance - 100  WHERE accountId = 'A1' AND balance >= 100;UPDATE "stage.Accounts" SET balance = balance + 100  WHERE accountId = 'B2';INSERT INTO "stage.Ledger" VALUE {'ledgerId': 'TX#124', 'amount': 100};COMMIT;
Executes asTransactWriteItems · [ UpdateItem ×2 · PutItem ×1 ] · ClientRequestToken set
  • A cancellation reports per-statement reasons instead of DynamoDB's opaque error; the status line reports the billed capacity (· 3 WCU).
Create related items together Native

A new order plus its first event — two entities of a single-table design that must never exist half-made.

sql
BEGIN TRANSACTION;INSERT INTO "stage.AppData" VALUE {'pk': 'ORDER#7', 'sk': 'META',  'status': 'open', 'CreatedAt': CURRENT_TIMESTAMP};INSERT INTO "stage.AppData" VALUE {'pk': 'ORDER#7', 'sk': 'EVT#0001',  'type': 'created', 'At': CURRENT_TIMESTAMP};COMMIT;
Executes asTransactWriteItems · PutItem ×2 — both stamped with the same instant
  • Clock functions render one shared instant across the block — the two CreatedAts can't drift.
Read two accounts from one consistent snapshot Native

Comparing balances mid-transfer lies unless both reads see the same instant — a read transaction serves every item from a single snapshot, which no sequence of individual reads can guarantee.

sql
BEGIN TRANSACTION;SELECT * FROM "stage.Accounts" WHERE accountId = 'A1';SELECT * FROM "stage.Accounts" WHERE accountId = 'B2';COMMIT;
Executes asTransactGetItems · 2 exact-key reads · one consistent snapshot
  • Reads skip the two-step ritual (nothing to double-apply) and run fine against a read-only stage. Each SELECT must be an exact key lookup — no extra predicates, LIMIT, ORDER BY, or aggregates.

Try it

Try it · TransactionSample
Executes asTransactWriteItems · 2 writes
TransactWriteItems [ UpdateItem ×2 ] · ConditionExpression on A1: balance >= :v · ClientRequestToken set
All-or-nothing: if A1 can't cover the debit, neither write lands.
Two-step run: first Run validates and previews; an unchanged second Run commits.
✓ Committed · 2 writes applied atomically · 2 WCU · idempotency token retained

Related: Writes & transactions · UPDATE · INSERT & upserts · keyword reference.

Was this page helpful?