ホームページ >データベース >mysql チュートリアル >データベースデッドロックの原因と解決策
データベース デッドロックの原因と解決策: 1. プログラムでバグが発生し、プログラムのロジックを調整する必要がある; 2. ページ上のボタンがすぐに有効にならず、オプティミスティック ロックと制御には悲観的ロックを使用する必要がある; 3.、条件を満たさない複数の更新ステートメントを実行する; ステートメントを分析し、最適化のために対応するインデックスを確立する必要がある。
データベース デッドロックの原因と解決策:
データベースには 2 つの基本的なタイプのロックがあります: 排他ロック
(排他ロック、つまり X ロック) および 共有ロック
(共有ロック、つまり S ロック)。データ オブジェクトが排他的にロックされている場合、他のトランザクションはそのデータ オブジェクトを読み取りまたは変更できません。共有ロックが設定されたデータ オブジェクトは、他のトランザクションから読み取ることはできますが、変更することはできません。データベースは、これら 2 つの基本的なロック タイプを使用して、データベース トランザクションの同時実行性を制御します。
関連するグラフィック チュートリアル: mysql データベース グラフィック チュートリアル
デッドロックの最初の状況
Aユーザー A がテーブル A にアクセスし (テーブル A をロック)、次にテーブル B にアクセスします。別のユーザー B がテーブル B にアクセスし (テーブル B をロック)、その後テーブル A にアクセスしようとします。この時点で、ユーザー B により、ユーザー A はテーブルをロックしています。 B. 続行するには、ユーザー B がテーブル B を解放するまで待つ必要があります。同様に、ユーザー B は、続行する前に、ユーザー A がテーブル A を解放するのを待つ必要があります。これにより、デッドロックが発生します。
解決策:
この種のデッドロックは比較的一般的で、プログラムのバグが原因で発生するため、プログラムのロジックを調整する以外に解決策はありません。プログラムのロジックを注意深く分析し、データベース内の複数のテーブルを操作する場合は、同じ順序で処理するようにし、2 つのリソースを同時にロックしないようにしてください。たとえば、2 つのテーブル A と B を操作する場合、常に処理が行われるようにしてください。最初に A、次に B の順序でロックします。 2 つのリソースを同時にロックする必要がある場合は、リソースが常に同じ順序でロックされるようにする必要があります。
デッドロックの 2 番目のケース
ユーザー A がレコードをクエリしてからレコードを変更し、次にユーザー B がレコードを変更し、次にユーザー A ロックの性質トランザクションはクエリの共有ロックから排他ロックに増やそうとしますが、ユーザー B の排他ロックは、A が共有ロックを解放するまで待つ必要があります。これは、A には共有ロックがあり、B の排他ロックのため A は増やせないためです。排他ロックでは共有ロックを解除することができないため、デッドロックが発生します。この種のデッドロックは比較的隠蔽されていますが、大規模なプロジェクトではよく発生します。たとえば、プロジェクトでは、ページ上のボタンをクリックした後、ボタンがすぐに無効にならず、ユーザーが同じボタンを素早く複数回クリックすることになります。このようにして、同じコード部分が同じコードに対して複数の操作を実行します。ロック状況。
解決策:
1. ボタンなどのコントロールについては、ユーザーが繰り返しクリックすることを防ぎ、同じレコードを同時に操作することを避けるために、クリックされた直後にコントロールを無効にします。同時。
2. 制御には楽観的ロックを使用します。オプティミスティック ロックは、ほとんどの場合、データ バージョン (Version) 記録メカニズムに基づいて実装されます。つまり、データにバージョン識別子を追加することです。データベース テーブルに基づくバージョン ソリューションでは、これは通常、データベース テーブルに「バージョン」フィールドを追加することによって実現されます。データを読み出す際にはこのバージョン番号も読み出され、その後更新されるとこのバージョン番号が1つインクリメントされる。この際、入稿データのバージョン情報とデータベーステーブルの該当レコードの現在のバージョン情報を比較し、入稿データのバージョン番号がデータベーステーブルの現在のバージョン番号より大きい場合は、更新されていない場合は、期限切れのデータとみなされます。オプティミスティック ロック メカニズムは、長いトランザクションにおけるデータベース ロックのオーバーヘッドを回避し (ユーザー A もユーザー B も操作中にデータベース データをロックしない)、大規模な同時実行下でのシステム全体のパフォーマンスを大幅に向上させます。 Hibernate には、データ アクセス エンジンにオプティミスティック ロックの実装が組み込まれています。オプティミスティック ロック メカニズムがシステムに実装されているため、外部システムからのユーザー更新操作はシステムによって制御されず、ダーティ データがデータベースに更新される可能性があることに注意してください。
3. 制御には悲観的ロックを使用します。ほとんどの場合、悲観的ロックは、操作の最大限の排他性を確保するために、Oracle の Select... for update ステートメントなどのデータベースのロック メカニズムに依存します。ただし、特に長いトランザクションの場合、データベースのパフォーマンスに大きなオーバーヘッドが発生し、耐えられないことがよくあります。たとえば、金融システムにおいて、オペレータがユーザー データを読み取り、読み取ったユーザー データに基づいて変更 (ユーザー アカウント残高の変更など) を行う場合、悲観的ロック メカニズムが使用されると、操作プロセス全体が無効になることを意味します。オペレーターがデータを読み込んで修正を開始してから修正結果を送信するまでの全プロセス、さらには途中でオペレーターがコーヒーを淹れに行った時間も含めて、データベースのレコードは常にロックされています。または何千もの同時実行があった場合、そのような状況は壊滅的な結果につながります。したがって、悲観的ロック制御を使用する場合は、慎重に検討する必要があります。
デッドロックの 3 番目の状況
条件を満たさない更新ステートメントがトランザクションで実行されると、フル テーブル スキャンが実行され、行レベルのロックがテーブル レベルのロックにアップグレードされます。このようなトランザクションが複数実行されると、デッドロックが発生します。ブロッキングが発生しやすくなります。テーブル内のデータ量が非常に多く、作成されたインデックスの数が少なすぎるか不適切な場合にも同様の状況が発生し、頻繁にフル テーブル スキャンが発生し、最終的にはアプリケーション システムの速度がますます遅くなり、最終的にはブロックまたはデッドロックが発生します。
解決策:
SQL ステートメントで複数のテーブルを関連付ける複雑すぎるクエリを使用しないでください。「実行プラン」を使用して SQL ステートメントを分析してください。完全なテーブルの場合はスキャンしてください。 SQL ステートメントを作成し、最適化のために対応するインデックスを作成します。
関連する学習に関する推奨事項: mysql ビデオ チュートリアル
以上がデータベースデッドロックの原因と解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。