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
