ロック待ち行列で待機しているリクエストは、ブロックされたリクエストと見なされます(ロックの重大度間の互換性を参照)。遅延状態にあるためにロックを付与されていないconsumeモードSELECTリクエストは、ブロックされているとは見なされません。しかし、そうしたリクエストが活動化してロック待ち行列に置かれると、そのリクエストはブロックされていると見なされます。明示的トランザクションの定義を参照してください。
リクエストがブロックされたと思われる場合には、Query Sessionユーティリティ(<Teradata Vantage™ - データベース ユーティリティ、B035-1102>を参照してください)を使用して、セッションの状況に関する懸念を肯定または否定することができます。
EXCLUSIVEロックとの互換性がない場合、数個のブロックされたリクエストが待ち行列に入れられて、それすべてはブロックしているEXCLUSIVEロックがシステムによって解放されるまで待機しなければならないという結果になることがあります。
ブロッキングとデッドロックは異なる
ロック マネージャがリクエストをロック待ち行列に入れると、そのリクエストは待ち行列の先頭に来たときにすぐに実行されることが知られています。ブロックされたリクエストがタイムアウトになることはありません。それらは先頭に到達するまで待ち行列にとどまり、到達すると待っていたロックが認められ、実行されます。
ロック マネージャが待ち行列に入れないリクエストは、LOCKINGリクエスト修飾子およびNOWAITオプションで明示的に指定されたものだけです(Teradata Vantage™ - SQLデータ操作言語、B035-1146を参照してください)。そのようなリクエストは、指定されたロックを取得できない場合に即時にアボートします。アボートしたリクエストを再度実行依頼することは、ユーザーの責任となります。
デッドロックは、何かの介入がなければ解決しないロック競合の状態です(デッドロックを参照してください)。Vantageの場合、介入は、デッドロックのより新しいリクエストをアボートすることにより実施されます。
デッドロックによってアボートされたリクエストの再試行可能なエラーが報告されることに注意してください。
同じテーブルのロックを要求する複数リクエスト トランザクションの処理
同じテーブルで競合するような複数のリクエストが、それぞれ独立した単一リクエストのトランザクションとして実行依頼された場合、Vantageはそれらのロック要件を、以下に示すプロセスで解決します。
- job_1には、table_aのREADロックが必要です。
table_aは解放されているため、このロックが認められ、job_1が処理を開始します。
- job_1はまだ実行中ですが、job_2にはWRITEロックが必要です。
このロックは有効状態のREADロックと衝突するため、WRITEロックは拒否され、job_2は待ち行列に入れられます。
- job_3にはACCESSロックが必要です。
ACCESSロックは、READロックともWRITEロックとも互換性があります(すなわち、job_1が完了して、READロックが解放されれば、job_3がACCESSロックを保持しているかどうかに関係なく、job_2は処理を開始できます)。したがって、このACCESSロックは認められ、job_3はjob_1と同時に実行できます。
- job_4にはREADロックが必要です。
これは、待ち行列内のWRITEロックと衝突するため、job_4は待ち行列内のjob_2の後ろに入れられます。
- job_5にはEXCLUSIVEロックが必要です。
EXCLUSIVEロックは、他のすべてのロックと衝突するため、job_5は待ち行列内のjob_4の後ろに入れられます。
- job_6にはACCESSロックが必要です。
これは、待ち行列内のEXCLUSIVEロックと衝突するため、job_6は待ち行列内のjob_5の後ろに入れられます。
ブロックされたリクエストの解決
注意深くセッションのスケジュールを立てることにより、ブロックされたリクエストがこうして限りなく待ち行列に入れられるのを防ぐことができます。
例えば、EXCLUSIVEロックが必要なリクエストを、処理にかかる時間および他のリクエストと関連するその機能に応じて、最初か最後に実行依頼することができます。他のリクエストがその変更に依存している場合は、最初に処理しなければなりません。
EXCLUSIVEロックが必要なリクエストの処理時間が長くなる場合は、バッチ ジョブとして空いた時間に実行することも考えられます。
複数リクエスト トランザクションの処理
明示的な複数リクエスト トランザクションも、スケジュール上の問題を再検討する必要があります。
単一トランザクション内の複数のリクエストによって競合するロックが必要になったときは、Vantageは、そのトランザクションが完了するまで、各リクエストのロックを順番に自動的に格上げします。
この処理方法は、活動中のトランザクションが新たに到着したトランザクションによって中断されることを防ぎます。しかし、活動中のトランザクションに多数のリクエストがある場合や長い処理時間を要する場合には、やはりブロックされた待ち行列が生じます。
例えば、次の状況について考えてみます。
ステップ | プロセス | |||
---|---|---|---|---|
トランザクション番号 | リクエスト | 必要なロック | 結果 | |
1 | 1 | SELECT … FROM table_a |
READ | table_aへのREADロックが認められ、SELECTリクエストの処理が開始します。 |
2 | 2 | INSERT INTO table_a … |
WRITE | トランザクション2は待ち行列に入れられます。これは、table_aへのWRITEロック リクエストが、すでにtable_aに設定されているREADロックと互換性がないからです。 |
3 | 1 | トランザクション1のSELECTリクエストの処理が完了します。 | ||
INSERT INTO table_a … |
WRITE | table_aのREADロックは、トランザクション1 INSERTリクエストのWRITEロックに格上げされます。 トランザクション2は引き続き待ち行列の中で非アクティブ状態にあり、table_aへのWRITEロック リクエストが許可されるのを待機します。 |