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