デッドロック(Deadlock)とは、複数の処理が、互いに相手の処理が終わるのを待ち続けてしまい、どちらも先へ進めなくなってしまう状態のことです。データベースの処理が複数同時に行われる際に発生することがあり、放置すると処理が永久に完了しません。
現実世界に例えると、デッドロックは狭い道ですれ違えなくなった2台の車のようなものです。お互いに「相手が先に譲ってくれるはず」と待ち続けてしまい、どちらも動けないまま立ち往生してしまう状況によく似ています。
デッドロック図解
デッドロックが発生する条件
| 処理 | 状況 |
|---|---|
| 処理A | データ1をロックし、データ2の解放を待っている |
| 処理B | データ2をロックし、データ1の解放を待っている |
ロックという仕組み
複数の処理が同じデータを同時に書き換えてしまうと、データの内容が壊れてしまうおそれがあるため、処理中のデータには一時的に他からの変更を防ぐ「ロック」がかけられます。このロックの取り合いが、デッドロックの直接的な原因となります。ロックの仕組み自体はデータを守るために必要なものですが、扱い方を誤ると行き詰まりを生んでしまいます。
デッドロックが起きるとどうなるか
デッドロックが発生すると、関係する処理はどちらも完了できないまま止まってしまい、システムの応答が返ってこなくなります。多くのデータベースでは、この状態を検知すると、どちらかの処理を強制的に中断させて解消する仕組みが備わっています。
デッドロックへの対策
デッドロックを防ぐ基本的な工夫として、複数のデータにアクセスする際の順序をあらかじめ統一しておくという方法があります。すべての処理が同じ順番でデータにアクセスすれば、互いに待ち合う状況が起こりにくくなります。
開発者が意識すべきこと
デッドロックは、アクセスが集中するシステムほど発生しやすくなる傾向があります。処理の設計段階からロックの範囲をできるだけ小さくし、処理時間を短く保つことが、デッドロックを避けるうえで重要な心がけとなります。
データベースによる自動的な検知
多くのデータベースには、デッドロックが発生していないかを定期的に監視する仕組みが組み込まれています。デッドロックを検知すると、影響の小さい方の処理を選んでロールバックさせ、もう一方の処理を先に進められるようにします。
アプリケーション側での対応
デッドロックによって処理が中断された場合、プログラム側であらためて同じ処理をやり直す「リトライ」の仕組みを組み込んでおくことも一般的です。利用者から見ると、一瞬の遅れだけで処理が完了したように見せることができます。


コメント