Oracle之DBMS_LOCK包用法詳解


概述與背景

 

某些並發程序,在高並發的情況下,必須控制好並發請求的運行時間和次序,來保證處理數據的正確性和完整性。對於並發請求的並發控制,EBS系統可以通過Concurrent Program定義界面的Incompatibilities功能配置實現。但是Incompatibilities功能存在其局限性,它只能把整個並發請求作為一個整體來判斷,並不能細化到並發請求的請求參數。而某些並發程序,只需要對其中某幾個參數做並發控制,例如時間段,OU等。對於這種業務需求,可以使用標准包DBMS_LOCK,把需要做並發控制的參數,加上鎖,實現並發控制。



 

DBMS_LOCK相關知識介紹

鎖模式

名字

描述

數據類型

nl_mode

Null

INTEGER

1

ss_mode

Sub Shared: used on an aggregate object to indicate that share locks are being acquired on subparts of the object

(對象的子部分,加上了Share鎖)

INTEGER

2

sx_mode

Sub Exclusive: used on an aggregate object to indicate that exclusive locks are being acquired on subparts of the object

(對象的子部分,加上了Exclusive鎖)

INTEGER

3

s_mode

Shared: indicates that the entire aggregate object has a share lock, but some of the sub-parts may additionally have exclusive locks

(對象加上了Share鎖)

INTEGER

4

ssx_mode

Shared SubExclusive

(對象加上了Share鎖,其子部分加上了Exclusive鎖)

INTEGER

5

x_mode

Exclusive

(對象加上了Exclusive鎖)

INTEGER

6

鎖兼容性

 

NL

SS

SX

S

SSX

X

NL

SUCC

SUCC

SUCC

SUCC

SUCC

SUCC

SS

SUCC

SUCC

SUCC

SUCC

SUCC

fail

SX

SUCC

SUCC

SUCC

fail

fail

fail

S

SUCC

SUCC

fail

SUCC

fail

fail

SSX

SUCC

SUCC

fail

fail

fail

fail

X

SUCC

fail

fail

fail

fail

fail

 

DBMS_LOCKProcedure

 

1、ALLOCATE_UNIQUE

dbms_lock.request(lockhandle        IN VARCHAR2,
                  lockmode          IN INTEGER DEFAULT x_mode,
                  timeout           IN INTEGER DEFAULT maxwait,
                  release_on_commit IN BOOLEAN DEFAULT FALSE) RETURN INTEGER;

說明:鎖模式轉換。

類型:Procedure

參數:

lockname:產生唯一的LockID。大小不超過128B,大小寫敏感。不能以'ORA$'字符串開頭,OracleProducts保留。如果lockname已分配LockID,則返回handle;否則,生成一個新的LockID,並返回handle

Lockhandle:返回值,requestconvertrelease調用。

expiration_secs執行'allocate_unique'后,Clean Up的時間間隔。

 

2、 CONVERT

dbms_lock.convert(lockhandle IN VARCHAR2,
                  lockmode   IN INTEGER,
                  timeout    IN NUMBER DEFAULT maxwait) RETURN INTEGER;

說明:鎖模式轉換。

類型:Function

參數:Lockhandleallocate_unique取得的handle

Lockmode:轉換的鎖模式。

Timeout:轉換等待時間。

返回值:

Return Values

 

0

Success

1

Timeout

2

Deadlock

3

Parameter error

4

Don't own lock specified by id or lockhandle

5

Illegal lock handle

 

3、RELEASE

dbms_lock.release(lockhandle IN VARCHAR2) RETURN INTEGER;

說明:釋放鎖。

類型:Function

參數:Lockhandleallocate_unique取得的handle

返回值:

Return Values

 

0

Success

3

Parameter error

4

Don't own lock specified by id or lockhandle

5

Illegal lock handle

 

4、REQUEST

dbms_lock.request(lockhandle        IN VARCHAR2,
                  lockmode          IN INTEGER DEFAULT x_mode,
                  timeout           IN INTEGER DEFAULT maxwait,
                  release_on_commit IN BOOLEAN DEFAULT FALSE) RETURN INTEGER;

說明:請求鎖。

類型:Function

參數:Lockhandleallocate_unique取得的handle

Lockmode:加鎖模式。

Timeout:轉換等待時間。

release_on_commitcommit或者rollback之后釋放鎖,默認False

返回值:

Return Values

 

0

Success

1

Timeout

2

Deadlock

3

Parameter error

4

Don't own lock specified by id or lockhandle

5

Illegal lock handle

 

5、SLEEP

dbms_lock.sleep(seconds IN NUMBER);

說明:Session睡眠。

類型:Procedure

參數:seconds:睡眠時間。

 

例子:

DECLARE
  -- lock
  l_lockname    VARCHAR2(100);
  l_lockhandle  VARCHAR2(200);
  l_lock_output NUMBER;
  l_locked      BOOLEAN := FALSE;
  g_pkg_name    VARCHAR2(240) := 'test_package';
  g_org_id      NUMBER := 125;
BEGIN
  /* 定義按何種方式並發(此處為同一個OU不能同時執行)
  * lockname類似於定義一個唯一的名字,當並發程序執行時就會去判斷是否這個唯一標識已經存在*/
  l_lockname := g_pkg_name || '_' || g_org_id;
  --根據l_lockname獲取唯一標識l_lockhandle
  dbms_lock.allocate_unique(lockname   => l_lockname,
                            lockhandle => l_lockhandle);
 
  /*用l_lockhandle這個唯一標識去給當前請求加鎖
  --  Return value:
  --    0 - success
  --    1 - timeout
  --    2 - deadlock
  --    3 - parameter error
  --    4 - already own lock specified by 'id' or 'lockhandle'
  --    5 - illegal lockhandle*/
  l_lock_output := dbms_lock.request(l_lockhandle,
                                     6,
                                     60,
                                     FALSE);
 
  IF l_lock_output <> 0 THEN
    --Output lock failure message
    RAISE apps.fnd_api.g_exc_error;
  END IF;
 
  --此處添加請求的業務邏輯
  --dbms_lock.sleep(seconds => 50);
 
  /*特別注意的是一定要將lockname釋放掉 否則這個並發就永遠別想再執行了*/
  IF l_lock_output = 0 THEN
    l_lock_output := dbms_lock.release(l_lockhandle);
  END IF;
EXCEPTION
  WHEN apps.fnd_api.g_exc_error THEN
    IF l_lock_output = 0 THEN
      l_lock_output := dbms_lock.release(l_lockhandle);
    END IF;
  WHEN OTHERS THEN
    IF l_lock_output = 0 THEN
      l_lock_output := dbms_lock.release(l_lockhandle);
    END IF;
END;

 

  • 大小: 41.9 KB
  • 大小: 35.7 KB


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM