先看一下各個包的接口與功能
--創建或得到同名鎖的句柄信息
DBMS_LOCK.ALLOCATE_UNIQUE (
lockname IN VARCHAR2, --想要獲得的鎖名稱
lockhandle OUT VARCHAR2, --返回的鎖句柄信息
expiration_secs IN INTEGER DEFAULT 864000); --距離最後一次分配多久後自動釋放該鎖
對鎖的類型進行轉換
DBMS_LOCK.CONVERT(
id IN INTEGER ||
lockhandle IN VARCHAR2, --鎖ID或鎖句柄
lockmode IN INTEGER, --新的鎖模式
timeout IN NUMBER DEFAULT MAXWAIT) --如果在指定的時間內得不到鎖,則返回1 請求(超時)
RETURN INTEGER;
通過鎖ID或句柄釋放鎖
DBMS_LOCK.RELEASE (
id IN INTEGER)
RETURN INTEGER;
DBMS_LOCK.RELEASE (
lockhandle IN VARCHAR2)
RETURN INTEGER;
拿到句柄申請鎖
DBMS_LOCK.REQUEST(
id IN INTEGER ||
lockhandle IN VARCHAR2,
lockmode IN INTEGER DEFAULT X_MODE,
timeout IN INTEGER DEFAULT MAXWAIT,
release_on_commit IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
休眠
DBMS_LOCK.SLEEP (
seconds IN NUMBER); 休眠時長(秒)
實驗:
Session 1
DECLARE
V_LOCK_HOLDER VARCHAR2(128);
BEGIN
DBMS_LOCK.ALLOCATE_UNIQUE('test_lockname', V_LOCK_HOLDER, 3600);
DBMS_OUTPUT.PUT_LINE(V_LOCK_HOLDER);
END;
#######################################################################################
10737418641073741864187
session2
DECLARE
V_LOCK_HOLDER VARCHAR2(128);
BEGIN
DBMS_LOCK.ALLOCATE_UNIQUE('test_lockname', V_LOCK_HOLDER, 3600);
DBMS_OUTPUT.PUT_LINE(V_LOCK_HOLDER);
END;
#######################################################################################
10737418641073741864187
點評:
先創建一個名字爲test_lockname的鎖
返回這個鎖的引用句柄 得到這個句柄的會話可以對鎖進行申請,轉換,釋放。
如果這個鎖已經存在 則並不會報錯 同樣返回這個鎖的句柄。
但是擁有句柄並不代表你可以使用這個鎖的資源,只不過是擁有申請的權利而已.
就好比你知道一個人的電話號碼,你可以打,但是能不能打通就不一定了。
然後再使用dbms_lock.REQUEST的這個過程 來申請鎖 申請到了才能用.
session 1
DECLARE
v_result NUMBER ;
BEGIN
v_result:= DBMS_LOCK.REQUEST('10737418641073741864187' ,DBMS_LOCK.X_MODE, 10, FALSE);
dbms_output.put_line(v_result);
END;
#######################################################################################
0
session 2
DECLARE
v_result NUMBER ;
BEGIN
dbms_output.put_line(to_char(SYSDATE,'hh24:mi:ss'));
v_result:= DBMS_LOCK.REQUEST('10737418641073741864187' ,DBMS_LOCK.X_MODE, 10, FALSE);
dbms_output.put_line(v_result);
dbms_output.put_line(to_char(SYSDATE,'hh24:mi:ss'));
END;
#######################################################################################
14:07:58
1
14:08:08
session 1
DECLARE
v_result NUMBER ;
BEGIN
v_result:= DBMS_LOCK.REQUEST('10737418641073741864187' ,DBMS_LOCK.X_MODE, 10, FALSE);
dbms_output.put_line(v_result);
END;
#######################################################################################
4
點評 :
當我們使用seesion1 第一次申請 很快就申請到了
當我們使用seesion2 申請並指定可以重試10秒時 一直到10秒之後才返回1 沒有申請到
當我們再是使用session1 申請時 返回值就會變成4 表示該會話已經擁有該鎖。
DBMS_LOCK.REQUEST的對應值列表如下:
0 Success
1 Timeout
2 Deadlock
3 Parameter error
4 Already own lock specified by id or lockhandle
5 Illegal lock handle
session 3
DECLARE
v_result NUMBER ;
BEGIN
v_result:=DBMS_LOCK.RELEASE('10737418641073741864187' );
dbms_output.put_line(v_result) ;
END ;
#######################################################################################
4
Session1
DECLARE
v_result NUMBER ;
BEGIN
v_result:=DBMS_LOCK.RELEASE('10737418641073741864187' );
dbms_output.put_line(v_result) ;
END ;
#######################################################################################
0
seesion2
DECLARE
v_result NUMBER ;
BEGIN
dbms_output.put_line(to_char(SYSDATE,'hh24:mi:ss'));
v_result:= DBMS_LOCK.REQUEST('10737418641073741864187' ,DBMS_LOCK.X_MODE, 10, FALSE);
dbms_output.put_line(v_result);
dbms_output.put_line(to_char(SYSDATE,'hh24:mi:ss'));
END;
#######################################################################################
14:26:45
0
14:26:45
點評
session3 試圖釋放一個由session1持有的鎖 但是沒有成功。返回值爲4
session1 對自己持有的鎖進行釋放,成功 返回0
此時seesion2再去申請該鎖,則很塊得到。
DBMS_LOCK.RELEASE
0 Success
3 Parameter error
4 Do not own lock specified by id or lockhandle
5 Illegal lock handle
還有一個轉換方法,也是需要所的持有者去做的,對應返回值列表
0 Success
1 Timeout
2 Deadlock
3 Parameter error
4 Don't own lock specified by id or lockhandle
5 Illegal lock handle
總結:
雖然Oracle的dbms_lock包提供了一套完整的鎖轉換機制。但是這個鎖本身只是一個信號量。
並沒有任何一個數據庫對象因爲該鎖的存在而被鎖定。
一般的應用還只是侷限於保證某些程序的串行化。
dbms_lock包的研究
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.