- Error number
- 1205
- SQLSTATE
HY000- Symbol
ER_LOCK_WAIT_TIMEOUT- Product
- MySQL Server
- Versions
- MySQL 5.7, 8.0 and 8.4 with InnoDB tables (default wait 50 seconds, innodb_lock_wait_timeout)
- Category
- Locking & Transactions
- Last reviewed
- 24 October 2026
On this page
What it means
Error 1205 means a statement waited longer than innodb_lock_wait_timeout for a row lock held by another transaction, so InnoDB gave up and rolled back that statement.
InnoDB locks the rows (and, for range conditions, the gaps between index records) that an UPDATE, DELETE, INSERT or locking read such as SELECT ... FOR UPDATE touches, and keeps those locks until the transaction commits or rolls back. Another transaction that needs one of those locks waits. If the lock is not released within innodb_lock_wait_timeout seconds (50 by default), the waiting statement fails with 1205. The session that gets the error is the victim of the wait, not the cause: the cause is the other transaction that is holding the lock, very often one that is idle and was never committed.
By default only the statement that timed out is rolled back, not the whole transaction (innodb_rollback_on_timeout is OFF). The transaction stays open with its earlier changes and locks, so the application must decide to retry the statement, or roll back and retry the transaction. This is different from a deadlock (1213), where InnoDB rolls back a whole transaction immediately. In SQL Server, by contrast, error 1205 is the deadlock error; see SQL Server 1222 for its lock timeout.
Common causes
- A transaction updated rows and then stayed open: an application that forgot to commit, a connection pool that keeps a transaction across requests, or an interactive client session left with autocommit off or after START TRANSACTION.
- A long batch job (a large UPDATE, DELETE or data migration) holds locks on many rows while short requests wait for them.
- A locking read (
SELECT ... FOR UPDATEorFOR SHARE) over a range locks the gaps as well, so INSERTs into that range wait. - A missing index makes an UPDATE or DELETE scan, and lock, far more rows than it changes.
- Work outside the database (an API call, a file upload, user think time) happens while the transaction holds row locks.
Diagnose it
Read-only These statements only read metadata (information_schema, performance_schema and SHOW statements) or your own data. They do not change data, privileges or configuration, so they are safe to run first.
Who is waiting and who is blocking (sys schema)
Run this while the wait is happening. waiting_pid and blocking_pid are connection ids (as in SHOW PROCESSLIST).
SELECT waiting_pid, waiting_query, blocking_pid, blocking_query,
wait_age_secs, locked_table, locked_index
FROM sys.innodb_lock_waits; One row per lock wait. blocking_query is the blocker's current statement, which is NULL (or unrelated) when the blocker is idle in an open transaction; the lock was taken by an earlier statement in that transaction.
Open transactions and how long they have been running
SELECT trx_id, trx_state, trx_started, trx_mysql_thread_id,
trx_rows_locked, trx_rows_modified, trx_query
FROM information_schema.innodb_trx
ORDER BY trx_started; The oldest transactions first. A transaction in state RUNNING with trx_query NULL and an old trx_started is idle with locks held, the usual cause of 1205. trx_state LOCK WAIT marks the waiting transactions.
The locks held and requested (performance_schema)
SELECT object_name, index_name, lock_type, lock_mode, lock_status, lock_data
FROM performance_schema.data_locks
WHERE object_schema = DATABASE();
SELECT requesting_engine_transaction_id, blocking_engine_transaction_id
FROM performance_schema.data_lock_waits; lock_status GRANTED rows are held, WAITING rows are blocked; lock_data shows the key value (for example the primary key 1). A lock_mode without REC_NOT_GAP, on a range, means a next-key lock that also blocks INSERTs into the gap.
Check the timeout setting and how often lock waits time out
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';
SHOW VARIABLES LIKE 'innodb_rollback_on_timeout';
SELECT name, count
FROM information_schema.innodb_metrics
WHERE name IN ('lock_timeouts', 'lock_row_lock_waits'); The wait in seconds (50 unless changed), whether a timeout rolls back the whole transaction (OFF by default), and the number of lock waits and timeouts since the server started. A count that keeps rising points to a recurring blocker rather than a one-off.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Commit or roll back the blocking transaction
Client or network sideFind the blocking_pid with the queries above, identify the application or user behind it (SHOW PROCESSLIST shows the user and host), and have it finish its transaction. Then fix the code path that leaves transactions open: commit straight after the related changes and never wait for users or external services inside a transaction.
End the blocking connection as a last resort
Changes database stateIf the blocker is abandoned (for example an idle session left open), ending its connection rolls back its transaction and releases the locks.
Caution: KILL rolls back all uncommitted work of that connection, and rolling back a large transaction can itself take a long time while it keeps its locks. Check the connection id, user and what the transaction has changed (trx_rows_modified) first, and agree it with the owner on a production server.
KILL 5389; -- the blocking_pid from sys.innodb_lock_waits
Retry correctly in the application
Client or network sideBecause only the statement was rolled back, decide explicitly: either roll back the whole transaction and retry it from the start (the simplest correct choice), or retry just the failed statement if the earlier work in the transaction is still wanted. Use a small number of retries with a short delay, and log the error so a recurring blocker is noticed.
Wait less, or not at all, where that is the better answer
Client or network sideFor interactive requests, a shorter session timeout gives faster feedback; for queue-style work, SKIP LOCKED takes the rows nobody else has locked, and NOWAIT fails at once (error 3572) instead of waiting. Both are available in MySQL 8.0.
Caution: Do not raise innodb_lock_wait_timeout with SET GLOBAL to hide the problem: every waiting request then hangs longer and connections pile up. Fix the long or idle transaction instead.
SET SESSION innodb_lock_wait_timeout = 5; -- this connection only
SELECT id, status
FROM orders
WHERE status = 'new'
ORDER BY id
LIMIT 10
FOR UPDATE SKIP LOCKED;
Make transactions lock fewer rows for less time
Changes schemaAdd an index for the WHERE clause of UPDATE and DELETE statements so InnoDB locks only the rows it changes, and split large batch updates into small committed chunks.
ALTER TABLE orders ADD INDEX ix_orders_status (status);
Examples
An open transaction blocks an UPDATE of the same row
Session B gets the error after the 1-second wait. In our run, B's transaction stayed open afterwards with its earlier changes (only the timed-out statement was rolled back).
CREATE TABLE accounts (
id INT PRIMARY KEY,
balance DECIMAL(10,2) NOT NULL
);
INSERT INTO accounts VALUES (1, 100.00), (2, 50.00);
-- Session A: changes a row and does not commit
START TRANSACTION;
UPDATE accounts SET balance = balance - 10 WHERE id = 1;
-- Session B (a second connection): needs the same row
SET SESSION innodb_lock_wait_timeout = 1; -- wait 1 second instead of 50
UPDATE accounts SET balance = balance + 10 WHERE id = 1; -- waits, then fails
-- Session A
ROLLBACK;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Reproduced on MySQL 8.0.46, 24 October 2026.
A range locked with FOR UPDATE blocks an INSERT
Under the default REPEATABLE READ isolation level the locking read takes next-key locks. In our run an INSERT for customer 8 also waited, while one for customer 20 succeeded at once.
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
status VARCHAR(20) NOT NULL,
KEY ix_orders_customer (customer_id)
);
INSERT INTO orders (customer_id, status) VALUES (5, 'paid'), (7, 'new'), (7, 'paid'), (9, 'new');
-- Session A: locks customer 7's orders (and the gaps around them)
START TRANSACTION;
SELECT id, status FROM orders WHERE customer_id = 7 FOR UPDATE;
-- Session B: adds an order for customer 7
SET SESSION innodb_lock_wait_timeout = 1;
INSERT INTO orders (customer_id, status) VALUES (7, 'new'); -- waits, then fails
-- Session A
ROLLBACK;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Reproduced on MySQL 8.0.46, 24 October 2026.
A plain SELECT reads at once, a locking read waits
CREATE TABLE orders (
id INT PRIMARY KEY,
status VARCHAR(20)
);
INSERT INTO orders VALUES (1, 'new'), (2, 'new');
-- Session A
START TRANSACTION;
UPDATE orders SET status = 'packing' WHERE id = 1;
-- Session B
SET SESSION innodb_lock_wait_timeout = 1;
SELECT id, status FROM orders WHERE id = 1; -- returns 'new' at once (consistent read)
SELECT id, status FROM orders WHERE id = 1 FOR UPDATE; -- waits, then fails
-- Session A
ROLLBACK;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Reproduced on MySQL 8.0.46, 24 October 2026.
How to prevent it
Keep transactions short: do the reads and calculations first, then open the transaction, make the related changes and commit at once. Never hold a transaction open across user input, network calls or a long loop, and make sure every code path (including errors) commits or rolls back. Index the columns used in UPDATE and DELETE conditions, and run big batch changes in small committed chunks outside peak hours.
Watch for it: alert on transactions in information_schema.innodb_trx that have been open longer than a few seconds, and on a rising lock_timeouts count. Handle 1205 in the application with a deliberate retry policy, remembering that the transaction is still open after the error.
Common questions
How do I fix MySQL error 1205 lock wait timeout exceeded?
While it is happening, query sys.innodb_lock_waits or information_schema.innodb_trx to find the transaction holding the lock, then get it committed or rolled back (KILL its connection only as a last resort). Then fix the code that keeps the transaction open, add missing indexes, and retry the failed work.
Does error 1205 roll back my transaction?
Not by default. InnoDB rolls back only the statement that timed out; earlier statements in the transaction stay in place and their locks are still held. Roll back yourself if you want to start again. The whole transaction is rolled back only when the server runs with innodb_rollback_on_timeout enabled, which can be set only at startup.
Should I increase innodb_lock_wait_timeout?
Usually not. A longer wait only makes requests hang longer behind the same blocker. Raise it for a single session that runs a long batch job if needed (SET SESSION), and fix the long or idle transaction that holds the lock.
What is the difference between 1205 and 1213?
1205 means a statement waited too long for a lock that another transaction still holds; only the statement is undone by default. 1213 means two transactions were waiting for each other (a deadlock); InnoDB detects it at once and rolls back one whole transaction.
Learn more on CodeWithSQL
Official documentation
- InnoDB startup options and system variables (innodb_lock_wait_timeout)
- InnoDB error handling
- The data_lock_waits table
- Locking reads (NOWAIT and SKIP LOCKED)
Last technically reviewed 24 October 2026; examples and diagnostics run on MySQL 8.0.46. Message templates checked against the server's error catalogue (perror) for that version.