2フェーズ ロック(2フェーズ ロックの定義を参照)で発生する可能性のある1つの問題は、2つのリクエストがそれぞれ別のデータベース リソースをロックし、もう一方がトランザクションを続行するためにそのリソースを必要とするという状況です。例えば、最初のトランザクションがテーブル行Bをロックし、2つ目のトランザクションがテーブル行Aをロックするという状況を考えてみてください。最初のトランザクションが続行できるようになるにはテーブル行Aをロックする必要があり、2つ目のトランザクションが続行できるようになるにはテーブル行Bをロックする必要がある場合、2つのトランザクションはデッドロックを形成します。各トランザクションは、続行できるようになるために、もう一方のトランザクションがロックされたリソースを解放するのを待機するため、この結果として抑制されるトランザクションは同時待機の状態になります。
これは個別のリクエストがロックの解放を待機していることとは異なる状況です。Teradataロックはタイムアウトしないので、リクエストは必要なロックが付与されるまでロック待ち行列の中で待機することに注意してください。例外はNO WAITオプションを、リクエストを変更するLOCKING句に指定する場合であり、この場合にはリクエストが即時にアボートして、それを含むトランザクションによるすべての更新がロールバックします。
例えば、同じAMPでの同じデータに対してREADロックを同時に保持していた2つのトランザクションが、両方とも更新リクエストに入ろうと試みると、ローカル デッドロックが発生します。
また、リクエストが複数のAMPで並列で処理されるために、グローバル デッドロックが発生する可能性があります。
例えば、transaction_aがAMP1上のobject_x (テーブルの、同じハッシュ値を共有する複数の行など)にWRITEロックを設定し、transaction_bがAMP2のobject_yにWRITEロックを設定するとします。 要求されるロックが両方とも許可されます。
次に、transaction_bがAMP1のobject_xにWRITEロックを設定しようとしますが、ブロックされます。同様に、transaction_aがAMP2のobject_yにWRITEロックを設定すると、これもブロックされます。どちらのトランザクションも完了することができなくなります。
DBQL Lock Loggerが有効になっている場合は、デッドロックが発生すると、XMLロック ロガー テーブルDBQLXMLLockTbl、およびメイン ログ テーブルDBQLogTblに記録されます。Viewpoint DBQLロック ロガー レポート ポートレットを使用すると、デッドロックが生じるたびにレポートを作成できます。このポートレットの使用法については、<Teradata® Viewpointユーザー ガイド、B035-2206>を参照してください。
デッドロックについて
トランザクション内の各リクエストは、実行中に独自のロックを設定して、トランザクションがコミットまたはロールバックするまで取得したロックを保持します。
この欠点は、同じデータベース オブジェクトに対して複数の同時アクセスが生じるときにデッドロックが発生する可能性があることです。この潜在的な問題に対するアプリケーション レベルの解決策は、必要なすべての明示的デーダベース レベル ロックおよびテーブル レベル ロックを、トランザクションの最初に単一のリクエストで適用することです。
デッドロックの検出
- AMP-ローカル
ローカル デッドロックは、1つのvproc内の局所的なAMP内のスレッド間の競合です。AMPローカル デッドロック検出ソフトウェアが、固定された30秒間隔でデッドロックの検査を行ないます。
- グローバル
グローバル デッドロックは、2つ以上の異なるAMPにわたるスレッド間の競合です。グローバル デッドロック検出は、DBS制御ユーティリティによりDeadLockTimeOutパラメータを使用して設定されたユーザー定義の期間に基づいて実行します。グローバル デッドロック検出ソフトウェアは、デフォルトでは4分間の期間に基づいて実行しますが、必要に応じて間隔をさらに短く設定することもできます。
Viewpointロック ロガー レポート ポートレットを使用して、ブロックされたトランザクションやグローバル デッドロックを検出します。このユーティリティ ポートレットの使用法については、<Teradata® Viewpointユーザー ガイド、B035-2206>を参照してください。
また、DBQLロギングからのXMLPLAN出力を使用して、デッドロックの状況を調べることもできます。領域管理の詳細について、<データベースの管理>を参照してください。
システムは、デッドロックを検出すると、トランザクションを終了してから、2つのうち後に開始されたトランザクションをロールバックします。
HUTロックおよび他のクライアント ユーティリティ ロックのデッドロックの検出と処理
ほとんどのクライアント ユーティリティはデータベース ロックを使用するため、グローバル デッドロック検出機能は、これらがデッドロックに陥る時期がわかります(グローバル デッドロック検出機能は、HUTデッドロックを検出しません)。デッドロックを解決するため、ロック マネージャはデッドロックしたトランザクションをアボートし更新内容をロールバックして、再試行可能な2631エラーを、要求しているアプリケーションまたはユーティリティに戻します。
以下のテーブルは、再試行可能な2631エラーが発生したときに、クライアント ユーティリティまたはアプリケーションから実行依頼されるトランザクションに何が発生するかを要約し、その問題に対する非常に基本的な解決法を示しています。
クライアント ユーティリティまたはアプリケーション | その他の条件 | 結果 |
---|---|---|
BTEQ | .SET RETRYがアクティブである。 | トランザクション全体がロールバックされても、BTEQは、トランザクション全体ではなく、トランザクションの失敗したリクエストおよびそれに続くリクエストのみを再試行します。 これが生じた場合、失敗したリクエストよりも前にトランザクション内のリクエストによって行なわれた更新と、トランザクションが進行中であることを示す文脈情報は消失します。 |
その他 | 以下を行なうためアプリケーションを記述する必要があります。
|
再試行可能なエラー2631の詳細については、<Teradata Vantage™ - Databaseメッセージ、B035-1096>を参照してください。