ねら~ITエンジニア雑記

やきうのお兄ちゃんが綴るOracle Databaseメインのブログ

複数セッションから DBMS_LOCK.ALLOCATE_UNIQUE を実行して、「enq: UL - contention」の P1, P2, P3 の違いを調べてみる。

「enq: UL - contention」は DBMS_LOCKパッケージ で 明示的 に
排他ロックを取得した場合に出る 待機イベント なんやで。彡(゚)(゚)

複数セッション で DBMS_LOCK.ALLOCATE_UNIQUE を実行して、
「enq: UL - contention」の P1, P2, P3 の違いを調べてみるやで。

ロック識別子には "AYU" と "SBT" の 2種類 を指定してみる。

-- Session1 識別子"AYU"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('AYU', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/

PL/SQL procedure successfully completed.

PRINT :v_lh;

V_LH
------------------------
10737421151073742115199 ★lockhandle値
-- Session2 識別子"AYU"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('AYU', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/
※待たされる。
-- Session3 識別子"AYU"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('AYU', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/
※待たされる。
-- Session4 識別子"SBT"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('SBT', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/

PL/SQL procedure successfully completed.

PRINT :v_lh;

V_LH
------------------------
10737421161073742116200 ★lockhandle値
-- Session5 識別子"SBT"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('SBT', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/
※待たされる。
-- Session6 識別子"SBT"のロックを取得
VAR v_lh VARCHAR2(128);
DECLARE
  n_res NUMBER;
BEGIN
  DBMS_LOCK.ALLOCATE_UNIQUE('SBT', :v_lh);
  n_res := DBMS_LOCK.REQUEST(:v_lh);
END;
/
※待たされる。

ちょっと冗長やったけど、これで仕込みは完了。この状態で V$SESSION を覗いてみると……

SET LINESIZE 300;
SET PAGESIZE 100;
COLUMN SID FORMAT 9999;
COLUMN SERIAL# 99999;
COLUMN EVENT FORMAT A30;
COLUMN P1_VC2 FORMAT A30;
COLUMN P2_VC2 FORMAT A30;
COLUMN P3_VC2 FORMAT A30;
SELECT SID, SERIAL#, EVENT, P1, P1RAW, P2, P2RAW, P3, P3RAW FROM V$SESSION
WHERE USERNAME = 'AYSHIBAT' ORDER BY EVENT, SID;
SID SERIAL# EVENT                                P1 P1RAW                    P2 P2RAW             P3 P3RAW
--- ------- ---------------------------- ---------- ---------------- ---------- ---------------- --- -----
143    1395 SQL*Net message from client  1650815232 0000000062657100          1 0000000000000001   0 00
209     927 SQL*Net message from client  1650815232 0000000062657100          1 0000000000000001   0 00
 70    7271 SQL*Net message to client    1650815232 0000000062657100          1 0000000000000001   0 00
 14     243 enq: UL - contention         1431044102 00000000554C0006 1073742116 0000000040000124   0 00
 83    4335 enq: UL - contention         1431044102 00000000554C0006 1073742116 0000000040000124   0 00
144     859 enq: UL - contention         1431044102 00000000554C0006 1073742115 0000000040000123   0 00
145    1601 enq: UL - contention         1431044102 00000000554C0006 1073742115 0000000040000123   0 00
                                   ^^^^^^^^^^ ^^^^^^^^^^^^^^^^★ここに注目
7 rows selected.

P1 ⇒ 違い無し。
P2 ⇒ lockhandle値(の 上10桁) が 入る模様
P3 ⇒ 値無し。

「enq: UL - contention」が発生している際に、1つのロックを奪い合っているのか
複数のロックを奪い合っているのか、P2を見たら良さげやな。彡(-)(-)

参考マニュアルは下記やで。lockhandle値は下記マニュアルの通りやね 彡(゚)(゚)

Oracle Database PL/SQLパッケージおよびタイプ・リファレンス
11g リリース2(11.2) B56262-06
83 DBMS_LOCK
http://docs.oracle.com/cd/E16338_01/appdev.112/b56262/d_lock.htm#i1002533
 > このプロシージャは、一意のロック識別子(1073741824から1999999999の範囲内)を
 > 指定のロック名に割り当てます。アプリケーションは、ロック識別子を使用して
 > ロックの使用方法を調整できます。これは、アプリケーションでロックの使用方法を
 > 調整するには、ロック番号よりロック名に基づいた方が容易になるためです。