Transactional DDL
DDL statements (CREATE, DROP, ALTER TABLE) that can be executed inside a transaction and rolled back.
transactional DDL rollback DDL atomic DDL DDL rollback
transaction DDL rollback create table drop table alter table
| Database | Status | Syntax Family | Min Version |
|---|---|---|---|
| PostgreSQL | full | - | - |
| MySQL | none | - | - |
| MariaDB | none | - | - |
| Oracle | none | - | - |
| SQL Server | full | - | - |
| SQLite | full | - | - |
| Redshift | partial | - | - |
| DB2 | partial | - | - |
| Snowflake | none | - | - |
| BigQuery | partial | - | - |
Compare Databases
Database Details
PostgreSQL
full
BEGIN;
CREATE TABLE foo (id INT);
ALTER TABLE foo ADD COLUMN name TEXT;
ROLLBACK;
-- The table foo does not exist after the rollback- All DDL participates in the open transaction and can be rolled back cleanly.
- Schema migrations can wrap their whole change set in a BEGIN ... COMMIT without a partial-failure mode.
Docs: Transactions, BEGIN
MySQL
none
- Every DDL statement implicit-commits before and after; user-level rollback of DDL is not possible.
- 8.0's atomic DDL is a crash-safety guarantee, not a rollback-inside-a-transaction guarantee.
Docs: Implicit Commit, Atomic DDL
MariaDB
none
- Same implicit-commit behavior as MySQL. 10.6+ atomic DDL covers crash recovery, not user rollback.
Oracle
none
- Every DDL implicit-commits before and after, including any pending DML in the current transaction.
SQL Server
full
BEGIN TRANSACTION;
CREATE TABLE foo (id INT);
CREATE INDEX idx_foo_id ON foo (id);
ROLLBACK;
-- The table foo does not exist after the rollback- Most DDL is transactional. Exceptions include CREATE DATABASE and DROP DATABASE.
- Schema migrations wrap the whole change set in BEGIN TRANSACTION ... COMMIT.
SQLite
full
BEGIN;
CREATE TABLE foo (id INTEGER PRIMARY KEY);
CREATE INDEX idx_foo_id ON foo (id);
ROLLBACK;
-- The table foo does not exist after the rollback- The entire write model is transactional, so DDL and DML behave the same way under BEGIN ... ROLLBACK.
Docs: Transaction Control
Redshift
partial
BEGIN;
CREATE TABLE foo (id INT);
ROLLBACK;
-- The table foo does not exist after the rollback- CREATE TABLE and DROP TABLE are transactional. Some ALTER variants and administrative commands are not, and behavior diverges from upstream PostgreSQL in places.
Docs: Serializable Isolation
DB2
partial
BEGIN;
CREATE TABLE foo (id INT);
ROLLBACK;
-- The table foo does not exist after the rollback- Most DDL is transactional, including column additions via ALTER TABLE. Exceptions: CREATE DATABASE and CREATE TABLESPACE.
Docs: Transaction Management
Snowflake
none
- Every DDL runs in its own implicit transaction. A DDL issued mid-transaction commits any pending DML before executing, and the DDL itself cannot be rolled back.
Docs: Transactions
BigQuery
partial
BEGIN TRANSACTION;
CREATE TEMP TABLE tmp_foo (id INT64);
INSERT INTO tmp_foo VALUES (1);
ROLLBACK TRANSACTION;- Single-statement DDL is atomic on its own.
- Multi-statement transactions accept DDL only on temporary objects: CREATE/DROP TEMP TABLE and TEMP FUNCTION. DDL on permanent tables inside a transaction is an error.