Deadlock Found
Two or more database transactions are blocking each other, creating a circular wait.
Explanation
Deadlock found occurs when two or more transactions are waiting for each other to release locks, creating a circular dependency that the database cannot resolve. For example, Transaction A locks Row 1 and waits for Row 2, while Transaction B locks Row 2 and waits for Row 1. The database detects this situation and kills one transaction (the deadlock victim) to allow the other to proceed. This is common in applications with concurrent database operations.
Common Causes
- Transactions acquiring locks in different order
- Long-running transactions holding locks
- Missing indexes causing table-level locks
- Concurrent write operations on same rows
- Lock escalation from row to table level
Solution
Ensure all transactions acquire locks in the same order to prevent circular waits. Keep transactions as short as possible to minimize lock duration. Use optimistic locking instead of pessimistic locking where appropriate. Implement retry logic for deadlock victims. Add proper indexes to reduce lock scope. Use SELECT ... FOR UPDATE carefully and only when necessary. Monitor deadlock logs to identify patterns. Consider using queue-based processing for operations that frequently deadlock.
Code Example
// Transaction A and B cause deadlock
// Transaction A:
DB::beginTransaction();
DB::table('accounts')->where('id', 1)->lockForUpdate();
DB::table('accounts')->where('id', 2)->lockForUpdate(); // waits!
// Transaction B (concurrent):
DB::beginTransaction();
DB::table('accounts')->where('id', 2)->lockForUpdate();
DB::table('accounts')->where('id', 1)->lockForUpdate(); // waits!
// DEADLOCK!
// Fix: always lock in same order
DB::beginTransaction();
DB::table('accounts')->where('id', 1)->lockForUpdate();
DB::table('accounts')->where('id', 2)->lockForUpdate();
// Transaction B does same order
// Retry logic
function executeWithRetry(callable $fn, int $retries = 3) {
for ($i = 0; $i < $retries; $i++) {
try {
return $fn();
} catch (QueryException $e) {
if ($e->errorInfo[1] == 1213 && $i < $retries - 1) {
usleep(100000); // 100ms delay
continue;
}
throw $e;
}
}
}
Error Information
Language
php
Difficulty
Advanced
Views
146
Related Errors
Database
Access Denied for User
The database rejected the connection because the username or password is incorrect.
Database
Data Truncation
The data being inserted or updated is too long for the column's defined size.
PHP
Call to a Member Function on Null
The code calls a method on a variable that is null instead of an object.
PHP
Fatal Error: Uncaught Error
An unhandled Error exception was thrown that crashed the script.