ORA-00054: ocupado com o recurso e adquirido com o NOWAIT especificado ou expirou o tempo-limite

Porque estou a obter este erro de base de dados quando actualizo uma tabela?

erro na linha 1: ORA-00054: o recurso ocupado e adquirido com o NOWAIT especificado ou o tempo-limite expirado

Author: Josep, 2011-01-30

13 answers

A sua mesa já está bloqueada por alguma consulta. Como você executou "select for update" e ainda não se comprometeu/rollback e novamente disparou select query. Faça um commit/rollback antes de executar a sua pesquisa.

 162
Author: user258367, 2011-01-30 12:02:20

A partir daqui ORA-00054: o recurso está ocupado e adquire com o NOWAIT indicado

Você também pode procurar o sql,nome de utilizador,máquina, informação de porta e chegar ao processo real que detém a conexão

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
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;
 76
Author: Abey Tom, 2017-05-23 12:10:40
Por Favor, Matem A Sessão Da Oráculo.

Usar a pesquisa abaixo para verificar a informação da sessão activa

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;

Matar como

alter system kill session 'SID,SERIAL#';

(por exemplo, alter system kill session '13,36543';)

Referência http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html

 43
Author: Chan Myae Thu, 2015-10-26 17:10:57
Há um trabalho muito fácil para este problema.

Se você executar um trace 10046 na sua sessão (google isto... too much to explain). Você verá que antes de qualquer operação DDL Oracle faz o seguinte:

BLOQUEAR A TABELA 'TABLE_NAME' NO WAIT

Se outra sessão tiver uma transacção aberta, obtém-se um erro. Então a solução é... tambores, por favor. Emite a tua própria fechadura perante o DDL e deixa de fora o "não esperar".

Nota Especial:

Se estiver a fazer dividir / largar partições oráculo apenas bloqueia a partição. -- podes bloquear a subparte da partição.

Então..... Os seguintes passos resolvem o problema.
  1. bloquear a tabela 'nome da tabela'; -- você irá ' esperar '(os programadores chamam a isto enforcamento). até a sessão com a transação aberta, commits. Isto é uma fila. então, pode haver várias sessões à sua frente. mas não te enganarás.
  2. executar o DDL. O seu DDL irá então abrir uma fechadura sem esperar. No entanto, a sua a sessão requisitou a fechadura. Então és bom.
  3. DDL auto-commits. Isto liberta as fechaduras.

As declarações DML irão ' esperar 'ou como os programadores lhe chamam' pendurar ' enquanto a tabela está bloqueada.

Uso isto em código que vai de um trabalho para largar partições. Funciona bem. Está em um banco de dados que está constantemente inserindo a uma taxa de várias centenas de inserções/segundo. Sem erros.

Se está a pensar. Fazendo isso em 11g. eu já fiz isso em 10g antes também no passado.

 14
Author: Bob, 2013-04-29 21:15:21

Este erro acontece quando o recurso está ocupado. Verifique se você tem quaisquer restrições de referência na consulta. Ou mesmo as tabelas que você mencionou na consulta podem estar ocupadas. Eles podem estar envolvidos com algum outro trabalho que será definitivamente listado nos seguintes resultados da consulta:

SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'

Encontra o SID,

SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id
 7
Author: Arunchunai vendan Pugalenthi, 2017-10-20 18:54:22

Isto acontece quando uma sessão diferente da usada para alterar uma tabela está a segurar um bloqueio, provavelmente devido a um DML (actualizar/apagar/inserir). Se você está desenvolvendo um novo sistema, é provável que você ou alguém em sua equipe emite a declaração de atualização e você poderia matar a sessão sem muitas consequências. Ou você pode se comprometer a partir dessa sessão uma vez que você sabe quem tem a sessão aberta.

Se tiver acesso a um sistema de administração SQL use-o para encontrar a sessão ofensiva. E talvez matar ele.

Você poderia usar a sessão V$E V$lock e outros, mas eu sugiro que você google como encontrar essa sessão e, em seguida, como matá-lo.

Num sistema de produção, depende. Para oracle 10g e mais velho, você poderia executar
LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);

Numa sessão separada, mas tenha o seguinte pronto, caso demore muito tempo.

alter system kill session '....

Depende do sistema que você tem, os sistemas mais antigos são mais propensos a não se comprometer de todas as vezes. Isso é um problema, uma vez que pode haver muito tempo fechaduras em pé. Por isso, a sua fechadura evitaria novas fechaduras e esperaria por uma fechadura que sabe-se lá quando será libertada. É por isso que tem a outra declaração pronta. Ou você pode procurar por scripts PLSQL lá fora que fazem coisas semelhantes automaticamente.

Na versão 11g existe uma nova variável de ambiente que define um tempo de espera. Acho que faz algo semelhante ao que descrevi. Lembre-se que os problemas de bloqueio não desaparecem.

ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);
Finalmente, talvez seja melhor esperar até lá. são poucos os usuários no sistema para fazer este tipo de manutenção.
 5
Author: Arturo Hernandez, 2013-07-15 19:49:57

O seu problema parece que está a misturar operações DML & DDL. Veja este URL que explica este problema:

Http://www.orafaq.com/forum/t/54714/2/

 4
Author: Shashi, 2011-05-05 12:37:43
Basta verificar o processo que está a aguentar a sessão e matá-lo. Está de volta ao normal.

Abaixo do SQL encontrará o seu processo

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;

Então mata-o

ALTER SYSTEM KILL SESSION 'sid,serial#'

Ou

Um exemplo que encontrei online parece precisar do ID da instância. alterar a sessão de remoção do sistema'130,620,@1';
 3
Author: Mathavan John, 2014-11-27 03:30:13
No meu caso, tinha a certeza de que era uma das minhas sessões que estava a bloquear. Portanto, era seguro fazer o seguinte:
  • Encontrei a sessão ofensiva com:

    SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';

    A sessão estava inactiva, mas ainda assim manteve a fechadura de alguma forma. Note que poderá ter de utilizar outros em que condição no seu caso (por exemplo, tente USERNAME ou MACHINE campos).

  • Matou a sessão usando o ID e SERIAL# adquirido acima:

    alter system kill session '<id>, <serial#>';

 2
Author: wrygiel, 2013-09-03 10:27:07

Consegui acertar este erro ao criar uma tabela! Obviamente não havia nenhum problema de discórdia em uma mesa que ainda não existia. A declaração CREATE TABLE continha uma cláusula CONSTRAINT fk_name FOREIGN KEY referente a uma tabela bem povoada. Tive de:

  • Remova a cláusula de chave externa da declaração da tabela CREATE
  • criar um índice na coluna FK
  • criar o FK
 1
Author: bwperrin, 2015-11-19 15:05:58
Tive um erro quando tinha dois guiões que estava a executar. Eu tinha ...
  • uma sessão SQL * Plus ligada directamente através de uma conta de utilizador schema (conta #1)
  • outra sessão SQL * Plus ligada usando uma conta de utilizador diferente do esquema( conta # 2), mas ligando-se através de uma ligação de base de dados como a primeira conta

Eu fiz uma queda de tabela, depois a criação de tabela como conta #1. Fiz uma actualização da mesa na sessão da conta nº2. Não efectuou alterações. Mesa de repetição programa drop / creation como conta #1. Ocorreu um erro no comando drop table x.

Resolvi-o executando COMMIT; na sessão SQL*Plus da conta #2.

 1
Author: vapcguy, 2017-05-23 19:46:27

Também Estou perante uma questão semelhante. Nada programador tem que fazer para resolver este erro. Informei a minha equipa oracle DBA. Eles cancelaram a sessão e funcionaram como um encanto.

 -3
Author: Shakeer Hussain, 2017-01-17 20:50:27
A solução dada pelo link da Shashi é a melhor... não é necessário contactar a dba ou outra pessoa

Faz uma cópia de segurança

create table xxxx_backup as select * from xxxx;

Apagar todas as linhas

delete from xxxx;
commit;

Insira a sua cópia de segurança.

insert into xxxx (select * from xxxx_backup);
commit;
 -5
Author: tafibo, 2013-03-27 09:23:41