InnoDB
では、自動的にトランザクションのデッドロックが検出され、デッドロックを解除するためにトランザクション (複数の場合あり) がロールバックされます。InnoDB
は、小さいトランザクションを選択してロールバックしようと試みます。トランザクションのサイズは、挿入、更新、または削除された行数によって決定されます。
InnoDB
は、innodb_table_locks = 1
(デフォルト) かつ autocommit = 0
の場合にテーブルロックを認識し、それよりも上位の MySQL レイヤーは、行レベルロックを識別します。それ以外の場合、InnoDB
は、MySQL LOCK TABLES
ステートメントで設定されたテーブルロックまたは InnoDB
以外のストレージエンジンで設定されたロックが関連しているデッドロックを検出できません。このような状況を解決するには、innodb_lock_wait_timeout
システム変数の値を設定します。
InnoDB
でトランザクションの完全なロールバックが実行されると、トランザクションで設定されたすべてのロックが解放されます。ただし、エラーの結果として単一の SQL ステートメントのみがロールバックされると、ステートメントで設定された一部のロックが保持される可能性があります。これが発生する原因は、InnoDB
では、どの行がどのステートメントで設定されたのかをあとで確認できないような形式で、行ロックが格納されるためです。
トランザクションで SELECT
がストアドファンクションを呼び出し、そのファンクション内のステートメントに失敗した場合は、そのステートメントがロールバックされます。さらに、そのあとで ROLLBACK
が実行された場合、トランザクション全体がロールバックされます。
デッドロックを回避するためにデータベース操作を編成する方法については、セクション14.2.11「デッドロックの対処方法」を参照してください。