まず、デッドロックは明示的なロックに依存しません。 MySQLのLOCKTABLEまたはデフォルト以外のトランザクション分離モードを使用する場合、デッドロックが発生する必要はありません。明示的なトランザクションを使用しない場合でも、デッドロックが発生する可能性があります。
デッドロックは、非常に簡単に1つのテーブルで発生する可能性があります。最も一般的には、単一のホットテーブルからのものです。
デッドロックはさらに すべてのトランザクションが単一行の挿入を行うだけの場合に発生します。
デッドロックが発生する可能性があります
- データベースへの複数の接続(明らかに)
- 内部で複数のロックを伴う操作。
明らかではないのは、ほとんどの場合、単一行の挿入または更新には複数のロックが含まれるということです。これは、挿入/更新中にセカンダリインデックスもロックする必要があるためです。
SELECTはロックされないため(デフォルトの分離モードを使用していて、FOR UPDATEを使用していない場合)、原因となることはありません。
SHOW ENGINEINNODBSTATUSはあなたの友達です。これにより、デッドロックに関する一連の(明らかに非常に紛らわしい)情報、特に最新の情報が得られます。
- デッドロックを完全に排除することはできません。デッドロックは本番環境で引き続き発生します(適切にストレスがかかっている場合は、テストシステムでも)
- デッドロックの量を非常に少なくすることを目指します。トランザクションの1%がデッドロックした場合、それは多すぎる可能性があります。
- 影響を完全に理解している場合は、トランザクションのトランザクション分離レベルを読み取りコミットに変更することを検討してください
- ソフトウェアがデッドロックを適切に処理するようにします。