
enq: UL – contention - 日本エクセム株式会社 Oracle待機イベント情報
目次[非表示]
- 1.基本情報
- 2.待機パラメータと待機時間
基本情報
DBMS_LOCKパッケージを使用すると、ユーザーが任意の仮想的なリソースのロックをかけることができます。DMLによって発生するロックの場合は、物理的なリソース(テーブル/トランザクション/セグメントなど)を必要としますが、DBMS_LOCKパッケージを使用する場合には、このような制限がありません。DBMS_LOCKパッケージを利用して取得するロックをUL(User-defined Lock)ロックと呼びます。ULロックを獲得するために待機しているセッションは、enq:UL – contentionイベントを待機します。
DBMS_LOCK.REQUEST関数を使用すると、ULロックをExclusiveに獲得し、DBMS_LOCK.RELEASE関数を使用すると、ロックを解除します。下のテストスクリプトを見てみましょう。
セッションA:(SID=156)
セッションB:(SID=151)
上記のように、セッションBはセッションAによって占められた”1″というリソースのロックを獲得するために待機することになります。この状態で、V$ LOCKビューを観察してみましょう。
セッションC:
テストULロック競合
セッションA(SID=156)は、ULロックを”1″と呼ばれるリソース(ID1=1)についてExclusiveに(lmode=6)獲得した状態であり、セッションB(SID=151)は、「1」という同じリソースにについてULロックをExclusiveに獲得するために待機していることを確認することができます。DBMS_LOCK.RELEASE関数を用いてロックを解除して、セッションBでの待機イベントを照会すると、以下のようにenq:UL – contention待機現象を観察することができます。
ULロックによる競合はDBMS_LOCKパッケージを効率的に使用していない場合に発生します。DBMS_LOCKパッケージは非常にシンプルでありながら柔軟で強力なブロッキング方法を提供しますが、ややもして間違って使用すると、致命的な競合を招くこともあることを留意しなければなりません。ULロックの解除は、基本的にロックを保有しているセッションでのみ可能です。したがって、特定のセッションがULロックを長時間保持することにより、同時実行の問題を起こしている場合、セッションを強制的に終了させること以外に選択肢がありません。DBMS_LOCK.REQUEST関数使用時、可能であればrelease_on_commitオプションを使用して不必要にロックを保持しないようにするのが良い方法です。このオプションを使用すると、コミットやロールバックが発生すると、トランザクションが保有していたULロックを自動的に解除します。
DBMS_LOCKパッケージに関連するもう一つの待機イベントがあります。DBMS_LOCK.SLEEPプロシージャを利用してトランザクションを一時停止する場合、そのプロセスは、PL/ SQL lock timerイベントを待機する。
PL/ SQL lock timer待機イベントによるパフォーマンスの問題はありません。もし、その待機が期待以上に高く出る場合、アプリケーションの実装ロジックに問題がないかどうか検討しなければなりません。
待機パラメータと待機時間
待機パラメータ
待機時間
enqueue待機イベントと同一に、最大3秒まで待ちます。もしULロックを獲得する場合は、獲得するまで待機します。