InnoDB
は自動的にトランザクションデッドロックを検出し、デッドロックを破壊するために
1
つ以上のトランザクションをロールバックします。InnoDB
は、トランザクションのサイズが挿入、更新、または削除された行数によって決定される小さいトランザクションを選んでロールバックしようとします。
InnoDB
は
innodb_table_locks = 1
(デフォルト) かつ
autocommit = 0
であればテーブルロックを認識しており、またそれより上位の
MySQL
レイヤは行レベルロックを識別します。そうでなければ、InnoDB
は MySQL LOCK
TABLES
ステートメントによるテーブルロックセットや
InnoDB
以外のストレージエンジンによるロックセットが関連しているデッドロックを検出することができません。innodb_lock_wait_timeout
システム変数の値を設定することによって、これらの状況を解決しなければいけません。
InnoDB
がトランザクションの完全なロールバックを実行するとき、トランザクションによって設定されるすべてのロックはリリースされます。しかし、もし単一
SQL
ステートメントだけがエラーの結果ロールバックされると、ステートメントによって設定されたいくつかのロックは維持されるかもしれません。これは、InnoDB
が、あとでどの行がどのステートメントによって設定されたのかということを確認することができないようなフォーマットで行ロックを格納するために起こります。
MySQL 5.1.24 以降でトランザクション内の
SELECT
がストアドファンクションを呼び出し、そのファンクション内のあるステートメントが失敗した場合、そのステートメントはロールバックされます。さらに、そのあとで
ROLLBACK
が実行された場合、トランザクション全体がロールバックされます。5.1.24
より前では、失敗したステートメントは失敗時にロールバックされませんでした
(ただし、これも最終的にはあとで、トランザクション全体をロールバックする
ROLLBACK
によっておそらくロールバックされる)。