Multi-statement transactions in Databricks: BEGIN ATOMIC for Delta and Iceberg tables
Since 14 October 2026, Databricks commits several SQL statements across several tables as one transaction: all of them or none. Write them between BEGIN ATOMIC and END, or BEGIN TRANSACTION and COMMIT on a SQL warehouse. Tables must be Unity Catalog managed Delta or Iceberg with catalog commits. What breaks without a transaction, the code with one, and the limits.
Tecyfy · Published · 8 min read

Since 14 October 2026, Databricks can commit several SQL statements across several tables as one transaction: either every change lands, or none does. Write the statements between BEGIN ATOMIC and END, and if any of them fails, Databricks rolls back the lot. The tables you write must be Unity Catalog managed Delta Lake or Iceberg tables with catalog commits turned on.
Delta tables have always been ACIDACID TransactionsThe 4 promises a database makes about a change: it happens completely or not at all, leaves valid data, does not see other changes half-done, and survives a crash once committed. one table at a time. What was missing was the same promise across 2 tables, which is what most real business changes touch.
What goes wrong without one
Take an order that must be recorded in 2 places: a row in orders and a stock reduction in inventory. Run the 2 statements one after the other, and if the second fails, the first has already committed. Now an order exists for stock that was never reserved, and the next job, dashboard or agent reads that half-finished state.
Run the 3 steps yourself, make the second one fail, and compare the tables with and without a transaction:
Step 2 fails, but step 1 has already committed. Order 1042 exists for 3 tins of tea that were never taken off the stock. Any job, dashboard or agent reading now sees a half-finished order.
Transactions across tables need Unity Catalog managed Delta or Iceberg tables with catalog commits. The order and stock figures are an example.
The code
The non-interactive form runs as one unit and rolls back on any error:
BEGIN ATOMIC
INSERT INTO shop.sales.orders (order_id, sku, qty)
VALUES (1042, 'TEA-01', 3);
UPDATE shop.sales.inventory
SET on_hand = on_hand - 3
WHERE sku = 'TEA-01';
INSERT INTO shop.sales.order_events (order_id, event)
VALUES (1042, 'reserved');
END;
To reject the whole thing on a business rule, not only on an error, use SIGNAL inside the block: a stock check that finds on_hand below 0 can raise an error and everything rolls back.
On a SQL warehouse you can also hold a transaction open and decide at the end:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- or ROLLBACK;
In this interactive form an error does not roll back for you: run ROLLBACK yourself. From Python, the Databricks SQL Connector does the same with autocommit=False, then commit() or rollback(); in a notebook, run the SQL through spark.sql().
Before it works: requirements
- Tables: writes only to Unity Catalog managed Delta or Iceberg tables with catalog commits (the
catalogManagedtable feature). External tables and path-based tables cannot be written in a transaction. That ties the feature to Unity CatalogUnity CatalogDatabricks' governance layer: one place that names every table, file volume, model and function as catalog.schema.object, decides who may use each, and records lineage and access.. - Compute:
BEGIN ATOMICruns on any SQL warehouse, serverless compute, or a cluster on Databricks Runtime 18.0 or later.BEGIN TRANSACTIONneeds a SQL warehouse. - Drivers: JDBC 3.0.5 or later, ODBC 2.10.0 or later.
How concurrent writers are handled
There are no locks. Databricks uses optimistic concurrency: each transaction works from a snapshot, and conflicts are checked at commit. If another writer changed the same rows first, your commit fails and you retry. Reads inside a transaction are repeatable: the first read of each table fixes the snapshot, and later reads in the same transaction see the same data. A transaction appears as one entry in each table's Delta log, so time travel shows it as a single change.
Limits to design around
| Limit | Value |
|---|---|
| Tables read or written | Up to 100 in total |
| Views read | Up to 100 |
| Intermediate commits per table | Up to 100 |
DDL (CREATE, ALTER, DROP) | Not allowed inside; run it before or after |
Time travel, SHOW TABLES, system tables | Not allowed inside |
| Interactive idle timeout | Rolled back after 10 minutes idle |
| Longest transaction | 48 hours |
One detail catches auditors: lineage events are kept even if the transaction rolls back, so lineage can show a write that never committed.
Where it helps most
- Loads that update a fact and its summary together, so a dashboard never shows totals that disagree with the detail.
- Corrections across tables, such as moving a customer's history after a merge of 2 accounts.
- AI agents that write data. An agent that books, refunds or updates records in several tables is exactly the writer you want all-or-nothing behaviour from.
For one table, plain MERGE was already atomic, so do not wrap every statement in a block. Use a transaction when correctness depends on 2 or more tables changing together. For how Delta LakeDelta LakeAn open table format that turns Parquet files in cloud storage into a table with transactions, a version history, schema checks, and updates and deletes, so a data lake behaves like a database. commits work underneath, and how Iceberg differs, see Delta Lake vs Apache Iceberg.
Questions
- Does Databricks support multi-statement transactions?
- Yes, generally available since 14 October 2026. Statements written between BEGIN ATOMIC and END, or between BEGIN TRANSACTION and COMMIT, commit together or not at all, across up to 100 tables. The tables you write must be Unity Catalog managed Delta Lake or Iceberg tables with catalog commits enabled.
- What is the difference between BEGIN ATOMIC and BEGIN TRANSACTION in Databricks?
- BEGIN ATOMIC ... END is non-interactive: the block runs as one unit, rolls back automatically if any statement fails, and runs on SQL warehouses, serverless compute or clusters on Databricks Runtime 18.0 and above. BEGIN TRANSACTION starts an interactive transaction on a SQL warehouse, where you run statements one at a time and finish with COMMIT or ROLLBACK.
- What happens if a statement fails inside a Databricks transaction?
- In a BEGIN ATOMIC block, any error rolls back the whole transaction automatically. In an interactive transaction you must run ROLLBACK yourself if the session is still open. A disconnect rolls back either kind, and an idle interactive transaction rolls back after 10 minutes.
- Can I run CREATE TABLE inside a Databricks transaction?
- No. DDL such as CREATE, ALTER and DROP TABLE must run outside the transaction. Time travel, SHOW commands and queries on system tables are also not allowed inside one.
- How does Databricks handle concurrent transactions?
- With optimistic concurrency control: there are no locks, and conflicts are checked at commit. If another writer changed the same data first, the transaction fails and must be retried. Reads inside a transaction are repeatable, because the first read of each table takes a snapshot that later reads reuse.
Sources