phacility/phabricator · warning · AphrontDeadlockQueryException
1213
1213
Error message
#%d: %s
What it means
MySQL errno 1213 'Deadlock found when trying to get lock', translated into AphrontDeadlockQueryException. Two transactions each hold locks the other needs; InnoDB detects the cycle and sacrifices one with this error. Deadlocks are normal in concurrent OLTP systems — the documented remedy is to roll back and retry the whole transaction, ideally in a new transaction. Phabricator marks this exception class as retryable and its workers re-run such queries.
Source
Thrown at src/infrastructure/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:338
}
$this->throwQueryCodeException($errno, $error);
}
private function throwCommonException($errno, $error) {
$message = pht('#%d: %s', $errno, $error);
switch ($errno) {
case 2013: // Connection Dropped
throw new AphrontConnectionLostQueryException($message);
case 2006: // Gone Away
$more = pht(
'This error may occur if your configured MySQL "wait_timeout" or '.
'"max_allowed_packet" values are too small. This may also indicate '.
'that something used the MySQL "KILL <process>" command to kill '.
'the connection running the query.');
throw new AphrontConnectionLostQueryException("{$message}\n\n{$more}");
case 1213: // Deadlock
throw new AphrontDeadlockQueryException($message);
case 1205: // Lock wait timeout exceeded
throw new AphrontLockTimeoutQueryException($message);
case 1062: // Duplicate Key
// NOTE: In some versions of MySQL we get a key name back here, but
// older versions just give us a key index ("key 2") so it's not
// portable to parse the key out of the error and attach it to the
// exception.
throw new AphrontDuplicateKeyQueryException($message);
case 1044: // Access denied to database
case 1142: // Access denied to table
case 1143: // Access denied to column
case 1227: // Access denied (e.g., no SUPER for SHOW SLAVE STATUS).
// See T13622. Try to help users figure out that this is a GRANT
// problem.
$more = pht(
'This error usually indicates that you need to "GRANT" the '.View on GitHub (pinned to 5720a38cfe)
Solutions
- Retry the transaction — this is the canonical fix; Phabricator daemons already retry deadlock exceptions automatically
- In custom scripts, wrap the whole unit of work and re-run it on AphrontDeadlockQueryException (new transaction, small backoff)
- Access rows in a consistent global order (e.g. ORDER BY id ... FOR UPDATE) to shrink deadlock windows
- Keep transactions short: avoid holding locks across slow computation or external calls
Example fix
// before: single attempt
$object->openTransaction(12); /* ...writes... */ $object->saveTransaction();
// after: retry the whole transaction on deadlock
$attempt = 0;
do {
try {
$object->openTransaction(12);
/* ...writes... */
$object->saveTransaction();
break;
} catch (AphrontDeadlockQueryException $ex) {
$object->killTransaction();
usleep(50000 * ++$attempt); // backoff 50ms, 100ms, ...
}
} while ($attempt < 5); Defensive patterns
Strategy: retry
Try / catch
try {
$object->openTransaction(12);
/* ...writes... */
$object->saveTransaction();
} catch (AphrontDeadlockQueryException $ex) {
$object->killTransaction();
usleep(100000); // small backoff, then retry the WHOLE transaction
} Prevention
- Retry the entire transaction on deadlock — never resume a partial one
- Touch rows in a consistent order (sorted by id) inside multi-row transactions
- Keep transactions short: no external calls or heavy computation while holding locks
When it happens
Trigger: Two workers updating overlapping rows in opposite orders (e.g. editing the same task's subpriority/transactions concurrently); batch scripts locking many rows in inconsistent order; transactions that read-then-write on the same keys racing each other.
Common situations: Bulk scripts adjusting task subpriorities or project memberships while users edit in the UI; heavy daemon activity on holidays/peak load; multiple queue workers processing tasks touching the same objects.
Related errors
- 1205
- Attempting to issue a write query on a read-only connection
- #%d: %s
- 2006
- Unable to establish a connection to any database host (while
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/75ef1b2365b24ac8.
Report an issue: GitHub.