A deadlock is a situation where different transactions are unable to proceed because each holds a lock that the other needs. Because both transactions are waiting for a resource to become available, neither ever release the locks it holds.
A deadlock can occur when transactions lock rows in multiple
tables (through statements such as
SELECT ... FOR
UPDATE), but in the opposite order. A deadlock can also
occur when such statements lock ranges of index records and gaps,
with each transaction acquiring some locks but not others due to a
timing issue. For a deadlock example, see
Section 18.104.22.168, “An InnoDB Deadlock Example”.
To reduce the possibility of deadlocks, use transactions rather
LOCK TABLES statements; keep
transactions that insert or update data small enough that they do
not stay open for long periods of time; when different
transactions update multiple tables or large ranges of rows, use
the same order of operations (such as
SELECT ... FOR
UPDATE) in each transaction; create indexes on the
columns used in
FOR UPDATE and
UPDATE ... WHERE
statements. The possibility of deadlocks is not affected by the
isolation level, because the isolation level changes the behavior
of read operations, while deadlocks occur because of write
operations. For more information about avoiding and recovering
from deadlock conditions, see
Section 22.214.171.124, “How to Minimize and Handle Deadlocks”.
If a deadlock does occur,
InnoDB detects the
condition and rolls back one of the transactions (the victim).
Thus, even if your application logic is correct, you must still
handle the case where a transaction must be retried. To see the
last deadlock in an
InnoDB user transaction,
INNODB STATUS command. If frequent deadlocks highlight a
problem with transaction structure or application error handling,
run with the
setting enabled to print information about all deadlocks to the
mysqld error log. For more information about
how deadlocks are automatically detected and handled, see
Section 126.96.36.199, “Deadlock Detection”.