Estou tentando entender porque ocorre um impasse no meu banco de dados. O rastreamento me diz que duas atualizações na mesma tabela estão bloqueando. In table é a primeira tabela a ser gravada em uma transação, apenas algumas leituras ocorrem antes. As atualizações/inserções são feitas em lote. A chave, que também é usada para identificar a linha a ser atualizada, é indexada com uma árvore b+. Essa chave também atua em outras tabelas como chave estrangeira. Nessas outras tabelas, a chave estrangeira pode ser nula.
O aplicativo não permite transações paralelas que contenham possíveis conflitos.
Aqui está o cabeçalho do arquivo de rastreamento:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-134b0012-3201376f 65 185 X 33 392 S
TX-13495007-50f092d1 33 392 X 65 185 S
session 185: DID 0001-0012-04533045 session 392: DID 0001-0023-03401G5A
session 392: DID 0001-0023-03401G5A session 185: DID 0001-0012-04533045
Rows waited on:
Session 588: no row
Session 497: no row
A inserção de um valor nulo em uma tabela referenciando a chave como uma chave estrangeira pode causar algum tipo de verificação da tabela (acho que não)? Uma inserção/atualização em lote pode fazer com que ramificações maiores de um índice sejam bloqueadas? Talvez T1 obtenha algum ramo esquerdo da árvore e T2 um ramo direito, e agora T1 deseja inserir/atualizar um valor no ramo direito, mas o ramo direito ainda está bloqueado por T2 e T" então solicita algo do lado esquerdo • Não faço ideia se e como o bloqueio de granularidade múltipla é implementado no Oracle, mas seria bom se alguém pudesse descartar isso.
Existe alguma possibilidade de o Oracle permitir deadlocks mesmo que as transações sejam 100% logicamente disjuntas?
O que eu poderia estar procurando? É algum problema para acessar o índice?
PS: leitura confirmada está definida.
Deadlocks no Oracle com transações logicamente separadas geralmente envolvem chaves estrangeiras não indexadas :
Os bloqueios no Oracle são gerenciados no nível da linha. Transações disjuntas simultâneas não devem interferir umas nas outras. Chaves estrangeiras não indexadas são uma exceção, pois podem resultar em um TABLE LOCK completo.
Você deve obter o SQL no arquivo de rastreamento do impasse e isso deve ajudá-lo a restringir qual tabela/chave estrangeira é responsável pelo bloqueio. Depois de saber qual tabela é afetada pelo impasse, certifique-se de que todas as referências de chave estrangeira a essa tabela estejam indexadas corretamente. EG em seu exemplo
T2.t1_id
deve ser indexado se apontar paraT1.t1_id
.Como alternativa, você pode usar o script de Tom Kyte no link acima para determinar se possui alguma chave estrangeira não indexada.
Se você está bloqueado em inserções, geralmente significa que está tentando inserir linhas com os mesmos valores para um conjunto de colunas UNIQUE, por exemplo: