Skip to main content

Fixed: "ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress" in MySQL

· 3 min read
Jagdish Kumawat
Founder @ Dewiride

Setting the isolation level failed with ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress. A transaction's isolation level is decided before it starts, so this one's a question of order.

What I Was Doing​

I was in a transaction on MySQL 9.7.4 in Docker, and decided the next part needed a stricter isolation level:

mysql
START TRANSACTION;
UPDATE products SET ReorderLevel = 5 WHERE Id = 3;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

What I Expected​

Query OK, and the rest of the transaction running at SERIALIZABLE.

What I Got​

Output (the last statement)
ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress

A mysql session where SET TRANSACTION ISOLATION LEVEL SERIALIZABLE inside a transaction fails with ERROR 1568 (25001).

What I Checked​

The transaction's real level. From a root session, the open transaction was running at the level it started with:

mysql: root session
SELECT trx_mysql_thread_id, trx_isolation_level FROM information_schema.innodb_trx;
Output
+---------------------+---------------------+
| trx_mysql_thread_id | trx_isolation_level |
+---------------------+---------------------+
| 72 | READ COMMITTED |
+---------------------+---------------------+
1 row in set (0.002 sec)

The SET TRANSACTION page. It says the statement "applies only to the next single transaction performed within the session." The next one, not the current one.

Why It Happens​

Isolation is a property of the whole transaction. MySQL can't change the rules halfway through, because what the transaction has already read and locked was done under the old ones.

The Fix​

End the transaction first, then set the level, then start the next one:

mysql
COMMIT;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
START TRANSACTION;
SELECT COUNT(*) FROM products;

After the Fix​

Output (SET TRANSACTION)
Query OK, 0 rows affected (0.000 sec)
Output (innodb_trx, from the root session)
+---------------------+---------------------+
| trx_mysql_thread_id | trx_isolation_level |
+---------------------+---------------------+
| 72 | SERIALIZABLE |
+---------------------+---------------------+
1 row in set (0.001 sec)

SET TRANSACTION succeeding after COMMIT, and information_schema.innodb_trx showing the next transaction running as SERIALIZABLE.

Common Mistakes​

MistakeWhat happensDo this instead
Setting the level after START TRANSACTIONERROR 1568Set it first
Writing SET TRANSACTION and expecting it to lastIt applies onceUse SET SESSION TRANSACTION
Committing just to get past the error, halfway through your workThe first half is saved, under the old levelPlan the level before you start

Troubleshooting​

SymptomLikely causeFix
The same error with READ ONLYThe same rule for the access modeSet it first
The error with no START TRANSACTION in sightautocommit = 0 keeps a transaction openCOMMIT first
The error from an applicationIt reuses a connection with an open transactionCheck that each path commits or rolls back

Conclusion​

ERROR 1568 means a transaction is open. End it, set the level, then start the next one. How to Check and Change the Transaction Isolation Level in MySQL covers the scopes.

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.