Deadlock com INSERT

É possível causar um Deadlock no Oracle com apenas uma tabela e INSERTs. O problema é causado pelos índices BITMAP, com índice B-TREE (o normal) isto não ocorreria.

Quando se insere um valor em uma coluna, todas as transações que alterem ou criem ocorrências deste valor terão que aguardar a conclusão da primeira transação, por COMMIT ou ROLLBACK.

Desta forma, em uma coluna indexada por índice Bitmap, ao inserir o número 1 em uma sessão, o 2 em outra, voltar na primeira sessão e inserir o número 2, e voltar na segunda sessão e inserir o número 1, ocorre o Deadlock: ambas sessões precisam que a outra termine para poderem prosseguir com a transação.

SESSÃO 1

C:UsersProni>sqlplus SCOTT/TIGER
SQL*Plus: Release 11.2.0.2.0 Production on Sex Jul 22 14:14:36 2011
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
SQL> CREATE TABLE T (COL1 NUMBER);
Tabela criada.
SQL> CREATE BITMAP INDEX IDX_T ON T(COL1);
-ndice criado.
SQL> INSERT INTO T VALUES (1);
1 linha criada.

SESSÃO 2

Microsoft Windows [versão 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Todos os direitos reservados.
C:UsersProni>sqlplus SCOTT/TIGER
SQL*Plus: Release 11.2.0.2.0 Production on Sex Jul 22 14:15:34 2011
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
SQL> INSERT INTO T VALUES (2);
1 linha criada.

SESSÃO 1:

SQL> INSERT INTO T VALUES (2);

Neste momento a Sessão 1 fica aguardando a conclusão da transação da Sessão 2.

SESSÃO 2:

SQL> INSERT INTO T VALUES (1);

Neste momento a Sessão 2 fica aguardando a conclusão da transação da Sessão 1, e logo uma das duas é considerada a vítima do Deadlock.

SESSÃO 1:

INSERT INTO T VALUES (2)
*
ERRO na linha 1:
ORA-00060: conflito detectado ao aguardar recurso

Neste momento a Sessão 2 continua aguardando a conclusão da transação da Sessão 1. Ao sair da Sessão 1, eu finalizo a transação, o que permite a Sessão 2 prosseguir.

SESSÃO 1:

SQL> EXIT;

SESSÃO 2:

1 linha criada.
SQL>

2 comments

  1. Aproveitando o tema, gostaria de saber se TODO Deadlock tem que ser resolvido pelo desenvolvedor ou há casos que é culpa é do banco de dados?

    1. Culpa é uma palavra muito forte. 🙂
      Há casos em que podemos ajudar sim.
      Se o Deadlock não envolve as mesmas linhas entre as duas sessões, a causa pode ser falta de ITL, que pode ser minimizada reduzindo a quantidade de linhas no bloco, via aumento do INITRANS do objeto ou em uma TABLESPACE de bloco menor.
      Então, vale a pena analisar o Trace do Deadlock.

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.