Skip to main content

Fixed: "ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction" in MySQL

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction means the statement tries to change something that a read-only transaction isn't allowed to touch. The straightforward case is an UPDATE, and the less obvious one is creating a temporary table.

What I Was Doing​

I had a report running in a read-only transaction, on MySQL 9.7.4 in Docker, and tried a small update in the same session:

mysql
START TRANSACTION READ ONLY;
UPDATE products SET QuantityOnHand = 49 WHERE Id = 3;

What I Expected​

Honestly, I'd forgotten which kind of transaction was open. I expected Query OK.

What I Got​

Output (the UPDATE)
ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.

An UPDATE inside START TRANSACTION READ ONLY failing with ERROR 1792 (25006).

A temporary table for the report's working data got the same answer:

mysql
START TRANSACTION READ ONLY;
CREATE TEMPORARY TABLE scratch2 (Id int PRIMARY KEY);
Output (the CREATE)
ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction.

What I Checked​

What READ ONLY covers. MySQL's START TRANSACTION page says: "The READ ONLY restriction prevents the transaction from modifying or locking both transactional and nontransactional tables that are visible to other transactions; the transaction can still modify or lock temporary tables."

Whether temporary tables work at all. They do, if the table already exists:

mysql
CREATE TEMPORARY TABLE scratch (Id int PRIMARY KEY);
START TRANSACTION READ ONLY;
INSERT INTO scratch VALUES (1);
COMMIT;
Output (the INSERT)
Query OK, 1 row affected (0.001 sec)

Why It Happens​

The transaction was opened with a promise not to write, and MySQL holds you to it. Creating a table counts as a change, even a temporary one, and writing to an existing temporary table doesn't.

The Fix​

If you meant to write, use an ordinary transaction. End the read-only one first:

mysql
COMMIT;
START TRANSACTION READ WRITE;
UPDATE products SET QuantityOnHand = 49 WHERE Id = 3;
SELECT Id, QuantityOnHand FROM products WHERE Id = 3;

READ WRITE is the default, so a plain START TRANSACTION does the same.

If you only need working space, create the temporary table before the transaction, as above.

After the Fix​

Output (the UPDATE, then the SELECT)
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Warnings: 0

+----+----------------+
| Id | QuantityOnHand |
+----+----------------+
| 3 | 49 |
+----+----------------+
1 row in set (0.001 sec)

The same UPDATE succeeding inside START TRANSACTION READ WRITE, and a SELECT showing the new quantity of 49.

Common Mistakes​

MistakeWhat happensDo this instead
Creating a temporary table inside the transactionERROR 1792Create it first
Mixing a report and a change in one transactionThe change is refusedUse two transactions
Forgetting a SET TRANSACTION READ ONLY from earlierThe next transaction refuses writesCheck what ran before it

Troubleshooting​

SymptomLikely causeFix
Cannot execute statement with no READ ONLY in your codeSET SESSION TRANSACTION READ ONLY was run, or the server is read-onlyCheck SELECT @@transaction_read_only
The same error with autocommit = 0The setting applies to every statementSET SESSION TRANSACTION READ WRITE

Conclusion​

ERROR 1792 means you're writing inside a transaction that promised not to. End it and open a normal one, and if you only need scratch space, create the temporary table before the transaction starts.

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.