Skip to main content

Fixed: ROLLBACK Doesn't Undo My Changes After CREATE TABLE in MySQL

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

I ran ROLLBACK, and MySQL answered Query OK, and my UPDATE was still there. A CREATE TABLE in between had quietly committed it. MySQL doesn't warn you, and the ROLLBACK has nothing to report.

What I Was Doing​

I was trying out a change in a transaction, so I could take it back, on MySQL 9.7.4 in Docker. Partway through, I created a small table to keep notes in:

mysql
START TRANSACTION;
UPDATE products SET QuantityOnHand = 49 WHERE Id = 3;
CREATE TABLE notes (Id int PRIMARY KEY);
ROLLBACK;
SELECT Id, Sku, QuantityOnHand FROM products WHERE Id = 3;

What I Expected​

The quantity back at 50, where it started.

What I Got​

Output (ROLLBACK, then the SELECT)
Query OK, 0 rows affected (0.001 sec)

+----+-------------+----------------+
| Id | Sku | QuantityOnHand |
+----+-------------+----------------+
| 3 | CBL-HDMI-2M | 49 |
+----+-------------+----------------+
1 row in set (0.001 sec)

A mysql session where ROLLBACK answers Query OK, and a SELECT still shows the quantity at 49.

What I Checked​

The docs. MySQL's implicit commit page says: "The statements listed in this section (and any synonyms for them) implicitly end any transaction active in the current session, as if you had done a COMMIT before executing the statement." CREATE TABLE is on the list.

Whether it needs to succeed. It doesn't. A TRUNCATE of a table that doesn't exist fails, and commits anyway:

Output (TRUNCATE TABLE __nosuchtable, then ROLLBACK and the SELECT)
ERROR 1146 (42S02): Table 'inventory.__nosuchtable' doesn't exist

+----+-------------+----------------+
| Id | Sku | QuantityOnHand |
+----+-------------+----------------+
| 3 | CBL-HDMI-2M | 49 |
+----+-------------+----------------+
1 row in set (0.001 sec)

Why It Happens​

MySQL can't roll back most changes to a table's structure, so those statements end your transaction first. By the time you run ROLLBACK, no transaction is open, and ROLLBACK succeeds at doing nothing.

The Fix​

The change can't be recovered by ROLLBACK now, so put the value back by hand if you need to. Next time, do the structure change outside the transaction:

mysql
CREATE TABLE notes (Id int PRIMARY KEY);
START TRANSACTION;
UPDATE products SET QuantityOnHand = 49 WHERE Id = 3;
ROLLBACK;
SELECT Id, Sku, QuantityOnHand FROM products WHERE Id = 3;

If you need a table only for this session, CREATE TEMPORARY TABLE doesn't commit, though it has its own small catch.

After the Fix​

Output (the SELECT)
+----+-------------+----------------+
| Id | Sku | QuantityOnHand |
+----+-------------+----------------+
| 3 | CBL-HDMI-2M | 50 |
+----+-------------+----------------+
1 row in set (0.001 sec)

With CREATE TABLE before START TRANSACTION, the ROLLBACK works and a SELECT shows the quantity back at 50.

Common Mistakes​

MistakeWhat happensDo this instead
Mixing structure changes and data changes in one transactionThe data changes are committed earlyKeep them separate
Reading Query OK from ROLLBACK as "it worked"It only means the statement ranCheck the data
Expecting a migration to roll back when it failsIts structure changes are already permanentWhich statements commit

Troubleshooting​

SymptomLikely causeFix
ROLLBACK didn't undo, with no CREATE TABLEA second START TRANSACTION, or autocommit was onCheck the statements in between
A table type with no transactionsROLLBACK can't affect a MyISAM tableUse InnoDB

Conclusion​

CREATE TABLE, ALTER TABLE, TRUNCATE and similar statements commit your open transaction, even if they fail, and ROLLBACK then has nothing to undo. Run them outside the transaction.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.