contention待機イベントは行レベル・ロックによる競合が発生したことを意味します。下記のような3つの場合に行レベル・ロック競合が発生します。複数セッションが同一行を更新する場合(モード6)TXロック競合が発生する最も一般的な原因には、同じ行を更新する場合があります。ITLから該当行を更新したトランザクションを確認します。contention待機イベントで待機します。この待機は、TXロックを保有したプロセスがロックを解除するまで発生し続けます。下記の例を見てみます。...セッションBはセッションAがすでに更新した行に対して、また更新をしようと要求しているため、待機状態におちいっている状況です。この状態でTXロックの待機状況をV$LOCKビューで確認すると、次の通りです。待機しているとのことが分かります。TXロックが保護するリソースはトランザクションであり、トランザクションの情報はUSN+SLOT+SQNの組み合わせで表現されます。TXロックのID1の値がこの組み合わせのUSN+SLOTまでの数字を表し、ID2の値がSQNを表します。このように、V$LOCKビューでは、どのようなトランザクションで競合が発生したのかを把握することができます。TXロックのID1、ID2値にそれぞれ結びつけられます。V$SESSION_WAITビューでセッションB(SID=148)の待機状況が確認できます。複数のセッションが一意キーで競合する場合(モード4)や、主キーで競合する時もTXロックが発生します。セッションBは共有モードでTXロックを獲得するため待機します。contention待機イベントが発生します。ロールバックを実行するまで待機します。セッションBではORA-0001エラーが発生しますが、ロールバックを実行すると正常にINSERTされます。一意キーを作成して、値をINSERTする。values(1);セッションB:(SID=148)同じ値をINSERTする。共有モードでTXロックを獲得するため待機V$LOCKビューの結果を確認してみると、先にINSERTを実行した144番セッションは一つのTXロック(ID1=917514、ID2=9024)を排他的に獲得しています。獲得した状態で、さらに144番セッションが保持しているTXロックを共有モードで獲得するために待機しています。このような現象からOracleが一意キーを保護するためにどのような方法を使っているのかが推論できます。ORA-0001エラーが発生します。そのトランザクションが獲得しているTXロックを共有モードで獲得するために待機するようになります。ビットマップ索引のリーフ・ノードはBツリー索引方式で管理されます。Bツリー索引のリーフ・ノードはソートされた形で索引エントリを保存し、個々の索引エントリは一つのROWIDを表します。従って、一意キー以外での索引エントリの間では競合が発生しません。ビットマップ値”の形になります。一つのリーフ・ノードが広い範囲のROWIDを管理するようになります。計算する必要があります。場合、順序を保障するためTXロックを獲得しなければなりません。待機するようになります。一つのリーフ・ノードが広い範囲のROWIDを管理するのでTXロック競合が広い範囲で発生する可能性があります。contention待機イベントで待機します。....2番目にINSERTを実行したセッションCは待機します。この状態で、V$LOCKビューを確認します。0-----------------V$LOCKビューから、先にINSERTを実行する148番セッションは一つのTXロック(ID1=4653100、ID2=440)を排他モードで獲得していることが分かります。148番セッションが保持しているTXロックを共有モード(request=4)で獲得するために待機しています。この結果は、一意キー競合による待機とまったく同一です。索引の正確な情報と同時に実行されたSQL文も考慮することだけが、正確な原因を見つけられる方法です。シーケンス待機時間1回の待機で最大3秒まで待ちますが、TXロックを獲得するまで待機します。同一行の更新によるTXロック競合は基本的にアプリケーション側の問題です。長時間実行されるUPDATEやDELETEコマンドはトランザクションが少ない時間帯に実行した方がいいです。UPDATEやDELETEコマンドそのものの性能を改善することも一つの方法です。大量データを更新することはTXロックの問題だけでなく、別の数多くの性能問題を引き起こす可能性があります。大量のUPDATEを避ける方法は次の通りです。old_table表をコピーし、new_table表を作成して更新内容を保存します。old_table”のようなコマンドを利用します。新しく作成したnew_table表にold_table表と同じく索引などを作成します。既存のold_table表をDROPして、new_table表をold_tableにリネームします。上記の作業を実行する時は、NOLOGGINGとPARARELLオプションを合わせて使用すると、より早く実行することができます。一意キーの競合によるTXロックはあくまでもアプリケーション側の問題です。一意キーの競合によるTXロックはいつでも発生する可能性があります。最善の解決策はシーケンスを使って一意キーを作成することです。最大化するために考案されたものです。DMLが頻繁な表に対してビットマップ索引をむやみに使うのはかなりリスクが高い方法です。行が更新される度にビットマップ値を計算しなければならないため、DMLの性能が低下します。同時に複数のセッションがDMLを実行する場合には、過度なTXロックが発生するようになります。同時ユーザー数が多いOLTP環境ではTXロックによる性能低下現象が発生する場合が多いです。MaxGaugeを活用してTXロックによる性能低下の原因を解析します。性能低下区間の確認14時05分~14時14分間にアクティブ・セッション数が急増していることが分かります。待機イベントを調査すると、下図のようにenqueue待機イベントが最も高い割合を占めていることが分かります。enqueue待機イベントを待機しています。Tree」で、TXロックを待機しているセッションを確認します。1178番セッションがロックを保持したセッションですが、他のセッションは排他モードのTXロックを獲得するために待機しています。ロックを保持したセッションが長時間もTXロックを解除しないため、enqueue待機イベントが多く発生しています。セッションおよびSQL分析ロックを保持している1178番セッションが実行したSQL履歴を検索すると、下図の通りです。ロックを保持したセッションはSQL文(<456130>)を実行した後、SQL文(<4618474>)を実行しました。最後のSQL文(<4618474>)を実行した後はそのまま、TXロックのenqueue待機イベントを待機します。ロックを保持したセッションはある行を更新した後、コミットを実行していない状態で、他の作業を実行している状況です。これによって同じ表の同じ行を更新しようとする他のセッションはTXロックでenqueue待機イベントを待機していました。表の行を更新した後、適切な時点でコミットをしなかったことが、enqueue待機イベントが発生した根本的な原因です。問題が発生したインスタンスのアクティブ・セッションの推移はエンキュー指標の推移と一致します。従って、アクティブ・セッションが90前後でセッション数を維持していたことは、エンキュー待機の発生と関連性があると考えられます。アクティブ・セッションのリストからでもセッションがTXエンキューを共有モードで待機していることが分かります。これらのセッションは全てINSERT文を実行しています。これらのセッションは共有モードで待機していることが分かります。(B_id,...)で、B表のB_idは主キー、すなわちユニークなキーです。下記のEmp表のEmpnoカラムに一意索引が作成されています。同じ値を入力した場合、24番セッションは21番セッションがコミットもしくはロールバックを実行するまでTXエンキューを共有モードで待機します。ロールバックを実行すると、正常にINSERTされます。このように一意制約のカラムに同じ値をINSERTした場合、先に実行したセッションがトランザクションを終了するまでTXエンキューが発生します。この場合は、シーケンスを利用して一意制約のカラムにINSERTを実行するように変更することで解決できます。解決策シーケンスを使用するようINSERT文を変更します。1シーケンスを使用する下記の表があります。SEQUENCEコマンドで、SEQ_IDというシーケンスを作成します。10000から増加3シーケンのNEXTVALで表にデータを入力します。現在シーケンスの値は次の値を返します。Page本サイトに掲載されている情報は日本エクセム株式会社が提供しています。