Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

NJM

Erro de mutating com Deadlock

Recommended Posts

Olá a todos, sou iniciante em oracle. Estou usando como linguagem o Delphi. Estou tentando colocar todas as regras gerenciais dentro do banco e me deparei com um problema. Acontece que tenho uma tabela pai (produto) e uma tabela filho (lote_produto), fiz uma trigger que dispara após deletar uma linha da tabela lote_produto, ele verifica se existe mais alguma linha daquele produto na lote_produto, caso não exista deve apagar a linha da tabela produto (pai), acontece que quando vou verificar se existe mais linhas da lote_produto ele dá erro de "mutanting", se coloca o "Pragma Autonomous_Transaction" ele até passa mas quando vai apagar a linha da produto dá erro de "deadlock", criei uma view para fazer este select e continuou com o erro de mutating, criei uma procedure para fazer o delete e continuou com o deadlock, não quero levar esta rotina para dentro do programa pois quero ter certeza da integridade dos dados. Alguem teria alguma sugestão para resolver este problema?

 

Obrigado, segue o codigo :

 

create or replace trigger TG_TESTE

after delete on lote_produto

for each row

declare

V_QTDE NUMBER(10,2);

Pragma Autonomous_Transaction;

begin

begin

SELECT COUNT(1) INTO V_QTDE FROM LOTE_PRODUTO

WHERE PRODUTO_LOTE_ID = :OLD.PRODUTO_LOTE_ID;

EXCEPTION WHEN NO_DATA_FOUND THEN

V_QTDE := 0;

END;

IF V_QTDE =0 THEN

DELETE FROM PRODUTO

WHERE PRODUTO_LOTE_ID = :OLD.PRODUTO_LOTE_ID;

END IF;

end TG_TESTE;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não tem um modo simples de evitar a "tabela mutante".

 

Tente fazer o seguinte : faça a trigger de statement ao invés de for each row.

 

A trigger de statement é executada após o fim da instrução, por ser de instrução não existem as variáveis new/old.

 

Verifique nesta trigger se existe registro "pai" sem "filho" e aí faça a deleção, esta verificação deve ser para toda a tabela e não apenas para o que foi deletado.

 

Esta trigger pode tornar a transação lenta, pois um delete de uma linha fará uma leitura na tabela toda.

 

Solução possível, criar uma procedura que faz esta limpeza é chamá-la pela aplicação.

--

Veja também :

Qual a opção de ON DELETE da tabela "pai" em relação à "filho" pois se está com ON DELETE CASCADE a delação da trigger faz a deleção em cascata que chama a trigger de forma recursiva, uma solução e usar ON DELETE SET NULL ou RESTRICT.

 

Para mais detalhes.

 

 

Espero ter ajudado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.