ORACLE報“ORA-00054:資源正忙,但指定以 NOWAIT 方式獲取資源,或者超時失效”的錯誤(v$locked_object、v$session、v$lock的使用)


一、錯誤類型

 

二、解決異常步驟

1、通常是因為增加或刪除數據沒有提交,執行一下commit就可以了

2、如果commit還不行,就執行以下命令。

1、SELECT SESSION_ID FROM V$LOCKED_OBJECT;
--查看被鎖對象的ID
2、SELECT SID,SERIAL#,USERNAME,OSUSER FROM V$SESSION WHERE SID=SESSION_ID;
--SESSION_ID是第一步查出來會話ID,查出session會話的sid和serial#
3、ALTER SYSTEM KILL SESSION 'SID,SERIAL#';
--對該會話進行終止.SID會被重用,同一個SID被重用時,SERIAL會增加,不會重復,所以結束會話時要指出SID和SERIAL#

3、通過sql輸出結束進程語句

select 'alter system kill session '''||sid||','||serial#||'''  immediate;' from v$session where sid in (select blocking_session from v$session) and seconds_in_wait>120
//將鎖定時間超過120秒的回話kill掉

 

三、視圖詳解

1、v$lock

查看數據庫中的鎖

select * from v$lock;
--SID:持有鎖的會話SID,與v$session相關聯
--TYPE:鎖的類型。TM表示表鎖或DML鎖,TX表示行鎖或事務鎖,UL表示用戶鎖。
--LMODE:會話保持的鎖的模式。0=NONE;1=NULL;2=ROW-S;3=ROW-X;4=SHARE;5=S/ROW-X;6=EXCLUSIVE。
--ID1/ID2:根據TYPE的值而定,主要是TM和TX。TYPE=TM時,ID1=OBJECT_ID,與DBA_OBJECTS相關聯,ID2=0
--REQUEST:REQUEST=n,表示該會話正在等待lmode=n的鎖
--BLOCK:該會話是否被鎖。0=沒被鎖;1=被鎖。

2、v$locked_object

查詢數據庫中被鎖的對象

SELECT * FROM V$LOCKED_OBJECT;
--OBJECT_ID:被鎖對象ID
--SESSION_ID:持有鎖的SESSION_ID
--ORACLE_USERNAME:持有鎖的ORACLE用戶名
--OS_USER_NAME:持有鎖的系統用戶名
--PROCESS:操作系統進程號
--LOCKED_MODE:鎖模式

3、v$session

查詢數據庫中的會話信息

SELECT * FROM V$SESSION;
--SADDR:會話地址
--SID:會話ID
--SERIAL#:SID會被重用,同一個SID被重用時,SERIAL會增加,不會重復

--PADDR:進程地址,關聯V$PROCESS的ADDR字段,關聯查出當前session對應操作系統的那個進程的id

--USER#:用戶名編號
--USERNAME:用戶名
--COMMAND:命令類型
--ONERID:所屬用戶的ID

--TADDR:事務地址,關聯V$TRANSACTION表的ADDR,關聯查出當前session正在使用的回滾段的情況

--LOCKWAIT:等到鎖的地址
--STATUS:會話狀態
--SERVER:服務器類型。
--PROCESS:操作系統客戶機進程ID
....

可以通過v$session查看阻塞會話a的會話b,最后阻塞會話a的會話c(b阻塞a,但是c是最后一個阻塞a),下面是做的一個小實驗:

conn hr/hr123;  //開啟會話1
select * from dept;  //在會話1修改DEPARTMENT_ID=100的行數據信息,但未提交
update dept set LOCATION_ID=1800 where DEPARTMENT_ID=100;
conn hr/hr123;  //開啟會話2
update dept set LOCATION_ID=1800 where DEPARTMENT_ID=100;  //對同一行進行操作,未能執行成功

//在會話3查詢阻塞的會話
conn hr/hr123;
select sid,serial#,blocking_session,final_blocking_session from v$session where BLOCKING_SESSION is not null or FINAL_BLOCKING_SESSION is not null;

顯示會話33被會話30阻塞了,通過阻塞會話sid查找sql_id,再查看具體的sql語句。

select sql_text from v$sql where sql_id in (select sql_id from v$session where sid=30);
select session_id,sql_id from v$active_session_history;  //查看每秒數據庫的會話信息

 

三、參考鏈接

1、異常解決方法參考鏈接

2、v$lock參考鏈接

3、v$locked_object參考鏈接

4、v$session參考鏈接


免責聲明!

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



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