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参考链接

posted @ 2021-11-23 23:19  微风徐徐$  阅读(8873)  评论(0编辑  收藏  举报