为什么我得到这个数据库错误时,我更新表?

第1行错误: ORA-00054:资源繁忙,指定NOWAIT或超时获取


当前回答

只需检查持有会话的进程并杀死它。一切恢复正常。

在SQL下面可以找到您的流程

SELECT s.inst_id,
   s.sid,
   s.serial#,
   p.spid,
   s.username,
   s.program FROM   gv$session s
   JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id;

然后杀死它

ALTER SYSTEM KILL SESSION 'sid,serial#'

OR

我在网上找到的一些例子似乎也需要实例id 删除系统会话:

其他回答

正如在其他回答中提到的,此错误是由在其他会话中运行的并发DML操作引起的。这将导致Oracle无法用默认的NOWAIT选项锁定DDL的表。

对于那些在数据库中没有管理权限或不能杀死/中断其他会话的用户,您还可以在DDL操作之前使用:

alter session set DDL_LOCK_TIMEOUT = 30;
--Run your DDL command, e.g.: alter table, etc.

我在后台作业执行大型插入/更新操作的数据库中反复收到此错误,在会话中更改此参数允许DDL在等待锁几秒钟后继续执行。

有关更多信息,请参阅rshdev对这个答案的注释、oracle-base上的这个条目或DDL_LOCK_TIMEOUT的官方文档。

就我而言,我很确定这是我自己的一个会话阻塞了。因此,这样做是安全的:

我发现了这个令人不快的环节: SELECT * FROM V$SESSION WHERE OSUSER='my_local_username' 会话处于非活动状态,但它仍然以某种方式持有锁。注意,在你的情况下,你可能需要使用一些其他的WHERE条件(例如,尝试USERNAME或MACHINE字段)。 使用上面获取的ID和SERIAL#杀死会话: 修改系统会话id为>,序列号为>

由@thermz编辑:如果前面的开放会话查询都不起作用,请尝试这个查询。这个查询可以帮助你在杀死会话时避免语法错误:

SELECT 'ALTER SYSTEM KILL SESSION ''||SID||','||SERIAL#||'' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'

Shashi的链接给出的解决方案是最好的…不需要联系dba或其他人

备份

create table xxxx_backup as select * from xxxx;

删除所有行

delete from xxxx;
commit;

插入备份。

insert into xxxx (select * from xxxx_backup);
commit;

请关闭Oracle会话

使用下面的查询来检查活动会话信息

SELECT
    O.OBJECT_NAME,
    S.SID,
    S.SERIAL#,
    P.SPID,
    S.PROGRAM,
    SQ.SQL_FULLTEXT,
    S.LOGON_TIME
FROM
    V$LOCKED_OBJECT L,
    DBA_OBJECTS O,
    V$SESSION S,
    V$PROCESS P,
    V$SQL SQ
WHERE
    L.OBJECT_ID = O.OBJECT_ID
    AND L.SESSION_ID = S.SID
    AND S.PADDR = P.ADDR
    AND S.SQL_ADDRESS = SQ.ADDRESS;

杀死像

alter system kill session 'SID,SERIAL#';

(例如,alter system kill session '13,36543';)

参考 http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html

您的表已经被某个查询锁定。例如,您可能已经执行了“select For update”,但尚未提交/回滚并触发另一个选择查询。在执行查询之前执行一次提交/回滚。