Skip to main content

Fixed: "ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set" in MySQL

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set isn't really a failure. You asked MySQL not to wait for a locked row, and the row was locked. The fix is deciding what your code does in that case.

What I Was Doing​

I wanted to work on a product, but only if nobody else had it, so I used NOWAIT, on MySQL 9.7.4 in Docker:

mysql
SELECT Id, QuantityOnHand FROM products WHERE Id = 3 FOR UPDATE NOWAIT;

What I Expected​

The row, locked for me.

What I Got​

Output
ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.

A mysql session where SELECT FOR UPDATE NOWAIT fails with ERROR 3572 (HY000): Statement aborted because lock(s) could not be acquired immediately and NOWAIT is set.

What I Checked​

Who held it. Another session had taken it first, and hadn't finished:

mysql: terminal 1
START TRANSACTION;
SELECT Id, QuantityOnHand FROM products WHERE Id = 3 FOR UPDATE;

What NOWAIT promises. The locking reads page describes the two options for not waiting. With NOWAIT, a locked row makes the statement fail instead of waiting.

Why It Happens​

Without NOWAIT, the statement would wait for the row, for up to 50 seconds by default. With it, MySQL reports the lock immediately, and the error is how it does that.

The Fix​

Choose what should happen when the row is taken:

You wantDo this
To tell the user it's busyCatch error 3572, and answer "someone else is working on this"
To try again shortlyCatch it, wait a moment, and run the statement again
To work on something elseUse SKIP LOCKED, which leaves the locked rows out
To wait your turnRemove NOWAIT

Here's the second one. The other session finishes:

mysql: terminal 1
COMMIT;

And the same statement runs again:

mysql
SELECT Id, QuantityOnHand FROM products WHERE Id = 3 FOR UPDATE NOWAIT;

After the Fix​

Output
+----+----------------+
| Id | QuantityOnHand |
+----+----------------+
| 3 | 50 |
+----+----------------+
1 row in set (0.000 sec)

The same SELECT FOR UPDATE NOWAIT returning the row once the other transaction had committed.

Common Mistakes​

MistakeWhat happensDo this instead
Treating it as a server problemNothing's wrong with the serverHandle it in your code
Retrying in a tight loopIt hammers the server for nothingWait a little between tries
Using NOWAIT with SKIP LOCKEDMySQL allows only one of themPick one
Forgetting the rest of the transactionEarlier statements are still pendingCommit or roll back deliberately

Troubleshooting​

SymptomLikely causeFix
It fails every timeSomething holds the row for a long timeSee who's blocking
You get ERROR 1205 and not thisThere's no NOWAIT, so it waited and timed outThe fix

FAQ​

Does the error end my transaction?​

No. Statements before it stay in the transaction, so you still have to commit or roll back.

Conclusion​

ERROR 3572 is NOWAIT doing what you asked: the row was taken, and MySQL said so at once. Catch it and tell the user, try again later, use SKIP LOCKED, or take NOWAIT out and wait.

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.