VillageSQL is a drop-in replacement for MySQL with extensions.
All examples in this guide work on VillageSQL. Install Now →
ERROR 1213: Deadlock found when trying to get lock; try restarting transaction.
How Deadlocks Happen
The classic pattern: two transactions lock rows in opposite order.Reading the Deadlock Log
The most recent deadlock is always available in the InnoDB status output:LATEST DETECTED DEADLOCK section. It shows both transactions, which locks they held, which locks they were waiting for, and which transaction was rolled back.
- Which two queries are in conflict
- What table and index is involved
- Which transaction was the victim (rolled back)
Deadlock Prevention Patterns
Lock rows in consistent order
The deadlock above happens because A locks row 1 then row 2, while B locks row 2 then row 1. If both transactions always lock in ascending ID order, the cycle can’t form:Keep transactions short
Longer transactions hold locks longer, giving more time for conflicts to develop. Do the minimum work inside a transaction:Use SELECT … FOR UPDATE to pre-lock
If your transaction will update a row, lock it on the SELECT rather than finding the lock collision on the UPDATE:Retry on deadlock
Deadlocks are expected in concurrent systems. The correct application response is to catchERROR 1213 and retry the entire transaction:
Gap Locks and Next-Key Locks
InnoDB uses gap locks and next-key locks to prevent phantom reads under the defaultREPEATABLE READ isolation level. These broader locks increase the chance of deadlocks.
READ COMMITTED uses row locks only (no gap locks), which reduces deadlock frequency. The trade-off is that it allows phantom reads. For most OLTP workloads, READ COMMITTED is a reasonable choice for deadlock-sensitive operations.
Lock Wait Timeout
Not all lock conflicts are deadlocks. If transaction B simply waits for A’s lock and A is slow, B will time out afterinnodb_lock_wait_timeout seconds (default: 50). The error is ERROR 1205: Lock wait timeout exceeded.
Frequently Asked Questions
How do I see all current locks and who’s waiting?
data_locks shows every lock currently held or requested. data_lock_waits shows which thread is blocking which.
Does InnoDB always detect deadlocks immediately?
InnoDB’s deadlock detector runs synchronously when a lock conflict occurs. Detection is nearly instant. You can disable it withinnodb_deadlock_detect = OFF and rely solely on innodb_lock_wait_timeout, which some high-concurrency workloads do for performance, but it’s unusual.
Can I prevent all deadlocks?
No. Deadlocks are a fundamental property of locking concurrent transactions. You can reduce their frequency with consistent lock ordering and short transactions, and you should always write retry logic for them.Troubleshooting
| Problem | Solution |
|---|---|
ERROR 1213: Deadlock found | Retry the transaction; inspect SHOW ENGINE INNODB STATUS for the lock conflict pattern |
ERROR 1205: Lock wait timeout exceeded | A transaction is holding a lock too long; find the blocking query in performance_schema.data_lock_waits |
| Deadlocks on INSERT, not UPDATE | Likely gap lock conflicts on an index range; try READ COMMITTED isolation or insert rows in a consistent order |
| Same deadlock pattern repeating | Lock ordering in the application is inconsistent — find the two code paths and enforce a canonical order |
SHOW ENGINE INNODB STATUS shows no deadlock | The status only retains the most recent deadlock; enable persistent deadlock logging to the error log: SET GLOBAL innodb_print_all_deadlocks = ON |

