<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

    業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
    創建自己的鎖定
    ?
    ??? 對于鎖定來說,盡管其概念比較復雜,但是Oracle將這些復雜性都屏蔽在Oracle的內核中。Oracle會自動完成鎖的管理,通常并不需要我們對鎖定進行很多的管理工作。不僅如此,Oracle還提供了相關的工具包:dbms_lock,使得我們可以創建自己的鎖定。
    ?
    ??? 通過dbms_lock,我們可以控制對某個設備(比如打印機)的串行訪問,或者控制對某個文件的串行寫入等。比如通過我們自己的應用程序打印數據時,要求在任意的時間點上,只能有一個用戶使用打印機。在具體實現時,我們可以創建一個打印機控制表。發出打印命令之前,先到該表里查詢打印標記,如果已經被設置為已打印,則說明其他用戶已經開始打印了,必須等待。如果打印標記還沒有被設置,則將打印標記更新為已打印,然后打印。在實現過程中,還要考慮多個用戶進程同時要求打印機時,所使用的排隊機制(通常都是先進先出)。通過這種借助表的方式,我們可以實現對打印機的串行訪問。不過,這種方式要執行SQL語句讀寫數據文件,相對性能較差。我們還可以有另一個選擇,就是調用dbms_lock創建自己的打印機鎖定。在打印前,獲得該打印機鎖定,打印以后釋放鎖定。在打印過程中,其他要獲得打印機的用戶進程進入隊列等待,并按照先進先出的方式管理該隊列。
    ?

    ??? 我們以上面描述的打印機為例,來說明如何使用dbms_lock包。
    ?
    ??? 分配打印機鎖定
    ?
    ??? 使用dbms_lock.allocate_unique存儲過程分配一個自定義的鎖定。如下所示:
    ?
    SQL> create or replace function get_lockhandle return varchar2
    ? 2? is
    ? 3???? printer_lockname VARCHAR2(128) := 'printer_lock';
    ? 4???? printer_handle??? VARCHAR2(128);
    ? 5? begin
    ? 6???? if printer_handle is null then
    ? 7??????? dbms_lock.allocate_unique
    ? 8?????????? (lockname => printer_lockname,
    ? 9??????????? lockhandle => printer_handle);
    ?10???? end if;
    ?11???? return printer_handle;
    ?12? end;
    ?13? /
    ?
    SQL> grant execute on get_lockhandle to public;
    ?
    ??? 我們在這里創建了一個函數,該函數中創建了一個名為printer_lock的函數。在調用dbms_lock. allocate_unique過程時,會返回該鎖定的句柄(lockhandle)。
    ?
    ??? 請求鎖定
    ?
    ??? 我們創建一個用于申請鎖定的存儲過程,如下所示:
    ?
    SQL> create or replace procedure lock_printer
    ? 2???? (p_return_code out integer)
    ? 3? is
    ? 4???? v_temp_lockhandle varchar2(128);
    ? 5???? v_call_status????? integer;
    ? 6? begin
    ? 7???? v_temp_lockhandle := get_lockhandle;
    ? 8???? v_call_status := dbms_lock.request
    ? 9?????? (lockhandle => v_temp_lockhandle,
    ?10??????? lockmode??? => dbms_lock.x_mode,
    ?11??????? timeout???? => 5,
    ?12??????? release_on_commit => true);
    ?13???? p_return_code := v_call_status;
    ?14? end lock_printer;
    ?15? /
    ?
    SQL> grant execute on lock_printer to public;
    ?
    ??? 在該存儲過程中,我們調用dbms_lock.request來申請打印機鎖定。在調用時,參數lockhandle為打印機鎖定的句柄;timeout表示請求鎖定時,如果5秒內不能獲得,則放棄獲得,而進入等待;release_on_commit表示發出commit或rollback命令時是否釋放鎖定。true為是,false為否;lockmode為打印模式,可選值如下表所示。
    ?
    鎖定模式 ??? 對應到TM鎖中的模式
    nl_mode null鎖定模式 Null
    ss_mode subshared鎖定模式 RS
    sx_mode subexclusive鎖定模式 RX
    s_mode shared鎖定模式 S
    ssx_mode subshared exclusive鎖定模式 RSX
    x_mode exclusive鎖定模式 X
    ?
    ??? 調用dbms_lock.request函數以后的返回值包括:
    ?
    返回值 含義
    0 申請鎖定成功
    1 申請鎖定時超時
    2 申請鎖定時發生死鎖
    3 傳入參數錯誤
    4 已經獲得了鎖定,重復申請了鎖
    5 傳入的鎖定句柄錯誤
    ?
    ?
    ??? 釋放鎖定
    ?
    ??? 我們創建如下的存儲過程來釋放打印機鎖定,其中調用了dbms_lock.release存儲過程。
    ?
    SQL> create or replace procedure release_printer
    ? 2? (p_return_code out integer)
    ? 3? is
    ? 4???? v_temp_lockhandle varchar2(128);
    ? 5???? v_call_status integer;
    ? 6? begin
    ? 7???? v_temp_lockhandle := get_lockhandle;
    ? 8???? v_call_status := dbms_lock.release
    ? 9?????? (lockhandle =>? v_temp_lockhandle);
    ?10???? p_return_code := v_call_status;
    ?11? end release_printer;
    ?12? /
    ?
    SQL> grant execute on release_printer to public;
    ?
    ??? 調用dbms_lock.release函數以后的返回值包括:
    ?
    返回值 含義
    0 釋放鎖定成功
    3 傳入參數錯誤
    4 并沒有獲得要釋放的鎖定
    5 傳入的鎖定句柄錯誤
    ?
    ??? 在創建了所有需要的存儲過程以后,我們來調用它們。打印前,執行下面的語句:
    ?
    SQL> select sid from v$mystat where rownum=1;
    SID
    ----------
    158
    ?
    SQL> var v_out number
    SQL> exec sys.lock_printer(:v_out);
    ?
    SQL> print v_out
    V_OUT
    ----------
    0
    ?
    ??? 申請鎖定以后,傳出參數的值為0,說明申請鎖定成功。然后我們檢查v$lock視圖:
    ?
    SQL> select sid,type,id1,id2,decode(lmode,0,'None',1,'Null',2,'Row share',
    ? 2???????? 3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')lock_mode,
    ? 3???????? decode(request,0,'None',1,'Null',2,'Row share',
    ? 4???????? 3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')request_ mode,block
    ? 5? ? from v$lock
    ? 6? where sid=158;
    ?
    SID??? TYPE??? ID1??????????? ID2????? LOCK_MODE REQUEST_MODE? BLOCK
    ----? ----- ----------- --------- -------------- ------------- -------
    158???? UL?? 1073742164??? ???? 0????? Exclusive???????? None?????? 0
    ?
    ?
    ??? 可以看到,獲得的鎖定類型為UL,表示用戶自定義的鎖定(User Lock)。只要是我們通過dbms_lock申請的鎖定,其type列都為UL;ID1表示鎖定的句柄;鎖定模式為排他鎖。根據ID1我們可以到dbms_lock_allocation視圖(該視圖顯示了已經分配的用戶自定義的鎖定信息)中找到該鎖定。
    ?
    SQL> select * from dbms_lock_allocated where lockid=1073742164;
    ?
    NAME????????? LOCKID?????????? EXPIRATION
    ------------- ---------------- -------------------
    printer_lock? 1073742164 ????? 2007-12-25 04:53:53
    ?

    ??? 然后我們再啟動一個session,并再次申請相同的打印機鎖定。
    ?
    SQL> select sid from v$mystat where rownum=1;
    SID
    ----------
    159
    ?
    SQL> var v_out number
    SQL> exec sys.lock_printer(:v_out);
    ?
    ?
    ??? 在執行lock_printer存儲過程時,會明顯感到延遲(其延遲時間長度就是我們前面在調用dbms_lock.request時指定的timeout參數,這里就是5秒鐘)。在延遲過程中,我們查詢v$lock視圖,會發現下面的信息:
    ?
    SQL> select sid,type,id1,id2,decode(lmode,0,'None',1,'Null',2,'Row share',
    ? 2???????? 3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_mode,
    ? 3???????? decode(request,0,'None',1,'Null',2,'Row share',
    ? 4???????? 3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') request_ mode,block
    ? 5? ? from v$lock6? where sid=158;
    ?
    ?SID TYPE??? ????? ID1???? ID2LOCK_MODE? ??? REQUEST_MODE ?? BLOCK
    ---- ----- ----------- ------- -------------- ------------- -------
    ?158 UL? ?? 1073742164?????? 0 Exclusive ???? None??????????????? 1
    ?159 UL? ?? 1073742164?????? 0 None ????????? Exclusive?????????? 0
    ?

    ??? 很明顯,159號session在以Exclusive模式申請打印機鎖定時,由于158號session已經持有該鎖定,因此發生等待。等待5秒鐘后,該存儲過程執行完畢,我們顯示v_out參數值:
    ?
    SQL> print v_out
    V_OUT
    ----------
    1
    ?
    ??? 返回值為1,說明申請鎖定時發生超時,因為其他進程已經獲得了該鎖定。
    ?
    ??? 從以上過程中,我們可以看到,通過使用dbms_lock,我們可以很方便地在自己的應用程序中實現串行化控制。
    ?
    ?
    posted on 2009-03-14 22:42 decode360 閱讀(158) 評論(0)  編輯  收藏 所屬分類: 06.PLSQL
    主站蜘蛛池模板: 国产亚洲日韩一区二区三区| 免费A级毛片无码无遮挡内射| 香蕉视频在线观看免费国产婷婷| 亚洲经典在线中文字幕| 99re6热视频精品免费观看| 久久亚洲精品成人av无码网站| 中文字幕看片在线a免费| 亚洲人妻av伦理| 久久免费香蕉视频| 久久青草亚洲AV无码麻豆| 97无码人妻福利免费公开在线视频 | 国产成人精品免费直播| 精品一区二区三区免费毛片| 亚洲福利中文字幕在线网址| 国产黄色免费观看| 亚洲亚洲人成综合网络| 国产va在线观看免费| 亚洲黄色免费在线观看| 久视频精品免费观看99| 国产亚洲精aa在线看| 国产美女被遭强高潮免费网站| 日本一区二区三区免费高清在线| 国产啪亚洲国产精品无码 | 免费黄色app网站| eeuss影院免费直达入口| 亚洲情综合五月天| 麻豆视频免费播放| 精品国产_亚洲人成在线| a级亚洲片精品久久久久久久 | 亚洲的天堂av无码| 免费在线观看中文字幕| 免费精品久久天干天干| 亚洲人色大成年网站在线观看| 国产精品成人无码免费| 国产又黄又爽胸又大免费视频 | 国产中文字幕免费观看| 永久免费A∨片在线观看| 亚洲制服丝袜一区二区三区| 免费va人成视频网站全| 日本一区二区免费看| 亚洲色丰满少妇高潮18p|