### 15.7.5 InnoDB 中的死锁

[15.7.5.1 InnoDB 死锁示例](innodb-deadlock-example.html)
[15.7.5.2 死锁检测](innodb-deadlock-detection.html)
[15.7.5.3 如何最小化和处理死锁](innodb-deadlocks-handling.html)

[](<>)[](<>)[](<>)[](<>)

死锁是一种不同事务无法继续进行的情况，因为每个事务都持有另一个需要的锁。因为两个事务都在等待资源变得可用，所以它们都不会释放它持有的锁。

当事务锁定多个表中的行时（通过诸如[`更新`](update.html)要么[`选择 ... 更新`](select.html))，但顺序相反。当此类语句锁定索引记录和间隙的范围时，也可能发生死锁，每个事务由于时间问题而获得一些锁，但没有获得其他锁。有关死锁示例，请参见[第 15.7.5.1 节，“InnoDB 死锁示例”](innodb-deadlock-example.html).

为了减少死锁的可能性，使用事务而不是[`锁定表`](lock-tables.html)陈述；保持插入或更新数据的事务足够小，以免它们长时间保持打开状态；当不同事务更新多张表或大范围的行时，使用相同的操作顺序（如[`选择 ... 更新`](select.html)) 在每笔交易中；在使用的列上创建索引[`选择 ... 更新`](select.html)和[`更新...在哪里`](update.html)陈述。死锁的可能性不受隔离级别的影响，因为隔离级别改变了读操作的行为，而死锁是因为写操作而发生的。有关避免和从死锁条件中恢复的更多信息，请参阅[第 15.7.5.3 节，“如何最小化和处理死锁”](innodb-deadlocks-handling.html).

当启用死锁检测（默认）并且确实发生死锁时，`InnoDB`检测条件并回滚其中一个事务（受害者）。如果使用禁用死锁检测[`innodb_deadlock_detect`](innodb-parameters.html#sysvar_innodb_deadlock_detect)多变的，`InnoDB`依赖于[`innodb_lock_wait_timeout`](innodb-parameters.html#sysvar_innodb_lock_wait_timeout)设置为在死锁的情况下回滚事务。因此，即使您的应用程序逻辑是正确的，您仍然必须处理必须重试事务的情况。查看最后一个死锁`InnoDB`用户交易，使用[`显示引擎 INNODB 状态`](show-engine.html).如果频繁的死锁突出了事务结构或应用程序错误处理的问题，启用[`innodb_print_all_deadlocks`](innodb-parameters.html#sysvar_innodb_print_all_deadlocks)将有关所有死锁的信息打印到[**mysqld**](mysqld.html)错误日志。有关如何自动检测和处理死锁的更多信息，请参阅[第 15.7.5.2 节，“死锁检测”](innodb-deadlock-detection.html).
