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
13
Related Errors
Database
Lock Wait Timeout Exceeded
A database query waited too long for a lock held by another transaction.
PHP
Include/Require File Not Found
The code tries to include or require a file that does not exist at the specified path.
Database
Database Connection Refused or Timeout
The database server is not reachable or took too long to respond.
PHP
Headers Already Sent
The code tries to send HTTP headers after output has already been sent to the browser.