Oracle 數據庫維護管理之--dbms_lock


1、查詢相關的v$視圖,但是提示表或視圖不存在解決辦法
     原因是使用的用戶沒有相關的查詢權限導致

     解決辦法:

       grant select  any dictionary to 用戶;    --這個權限比較大 

       grant select_catalog_role to 用戶;  --這個權限是最低的要求,但是可以訪問到v$相關視圖

       收回權限  

       revoke select_catalog_role from 用戶;

       結果:

 

2、其中我們需要登錄sys或者system級別的用戶才可以進行這方面的授權

     sys用戶,默認的登錄密碼是change_on_install as sysdba

 3、我們可以使用dbms_lock進行多會話(多機)模式下,共享代碼片段訪問的控制。

--假設我們要控制訪問的共享代碼片段
create or replace function fun_wxc(p1 in varchar2
)
return number is
  rs number;
begin
  rs := p1;
  sys.dbms_lock.sleep(25);
  return rs;
end;

會訪問到我們的共享代碼片段的存儲過程,我們需要在其中控制訪問的可入性:

create or replace procedure p_enqueue_test(p_lock_mode  number,   --請求獲取的鎖模式
                                           p_lock_expired  number --請求鎖等待超時時間
   ) is
  lock_name   varchar2(100):='fun_wxc_2';
  lock_handle varchar2(100);
  lock_is_get number;
begin
  --打印會話信息
  dbms_output.put_line('--------------------->session start<---------------------');
  --lockname 類似於定義一個資源的名稱,用於並發控制程序判斷當前這個資源有沒有被鎖定
  --產生鎖
  dbms_lock.allocate_unique(lockname => lock_name, 
lockhandle => lock_handle); dbms_output.put_line('the lock handle is ' || lock_handle); dbms_output.put_line('lock request start time is ' ||to_char((sysdate), 'yyyy/mm/dd hh24:mi:ss')); --請求鎖,如果代碼已經被執行(即公共代碼正在被執行),鎖請求等待p_lock_expired秒后超時退出 lock_is_get := dbms_lock.request(lock_handle, p_lock_mode, p_lock_expired, false); --判鎖獲取是否成功,不成功則不能執行公共代碼塊 if lock_is_get <> 0 then dbms_output.put_line('the procedure is executing,can not call it in the same time'); end if;
--請求鎖成功 if lock_is_get = 0 then dbms_output.put_line('the lock request seccuss,execute start time is ' ||to_char((sysdate), 'yyyy/mm/dd hh24:mi:ss')); --要執行的代碼開始 declare r1 number; begin r1 := fun_wxc(2);--這段代碼沒有被其他會話執行中,所以啟動這段代碼 dbms_output.put_line('the procedure has been executed,finish time is ' || to_char((sysdate), 'yyyy/mm/dd hh24:mi:ss'));--要執行的代碼結束 end; lock_is_get := dbms_lock.release(lock_handle);--執行完成后釋放鎖 end if; end p_enqueue_test;

同時開5個sqlplus 窗口,模擬5個並發會話(多機)要同時執行函數fun_wxc的場景

開始后5個會話依次完成,結果如下

會話1以共享模式獲取資源fun_wxc上的鎖,成功

會話2以共享模式獲取資源fun_wxc上的鎖,因為鎖模式與會話1是兼容的,所以可以成功獲取鎖,並且與會話1幾乎同時完成,如下時間所示

會話3以排他模式獲取資源fun_wxc上的鎖,因為鎖模式與會話1產生的鎖是不兼容的,所以可以被阻塞在等待者隊列中,到會話1,2完成后釋放資源,最終獲取到了鎖資源並且成功執行(注意共享代碼塊的啟動時間),如下時間所示

會話4以共享模式獲取資源fun_wxc上的鎖,因為鎖模式與會話3產生的鎖是不兼容的,所以可以被阻塞在等待者隊列中,到會話3完成后釋放資源,最終獲取到了鎖資源並且成功執行(注意共享代碼塊的啟動時間),如下時間所示

會話5以排他模式獲取資源fun_wxc上的鎖,因為鎖模式與會話4產生的鎖是不兼容的,所以可以被阻塞在等待者隊列中,但是(經歷會話1、2共25s+會話3共25s+會話4共25s=75s等待)等待超時了,所以因超時放棄執行(注意超時信息打印時間),如下時間所示

在v$lock 並中也可以監控到執行時候的排隊情況,如下

我們使用的查看鎖腳本語句是:select * from v$lock;

可以看到,兩個會話同時到達公共代碼塊的入口前一行代碼進行鎖的申請,由於我們手動啟動是先啟動會話1的,會話1取得了鎖並且是排他鎖,所以會話2處於等待狀態,等待鎖獲取時間為10s,而會話1執行的時間是25s(使用系統睡眠函數進行模擬替代),最終在會話1釋放鎖之前,會話2因為請求鎖超時而自動退出,會話1執行完公共代碼塊后,釋放鎖資源。

總結:在多會話的情境下,我們可以使用dbms_lock提供的鎖機制控制並發執行。

文章參考:http://www.cnblogs.com/wangxingc/p/6179901.html#undefined

 


免責聲明!

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



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