Olá DBAs! Hoje vamos falar a respeito do tão temido Deadlock no banco de dados Oracle.
Deadlocks são eventos que acontecem em sistemas de banco de dados quando duas ou mais transações se bloqueiam mutuamente, resultando em uma situação em que nenhuma delas consegue avançar. Isso normalmente ocorre quando cada transação está esperando por recursos que estão sendo mantidos pela outra, criando um impasse que pode impedir o progresso de todo o sistema.
1. O Que é um Deadlock?
Um deadlock acontece quando há um ciclo de dependências entre transações e cada transação detém um recurso que a outra transação necessita. No Oracle, isso geralmente se manifesta com o erro ORA-00060: deadlock detected while waiting for resource.
2. Causas Comuns de Deadlocks
As causas de deadlocks no Oracle podem incluir:
- Locks incompatíveis: Quando transações diferentes tentam adquirir locks em ordens conflitantes.
- Dependências circulares: Quando cada transação espera por um recurso que a outra transação detém.
- Índices Bitmap: Podem causar deadlocks em situações específicas, ao contrário dos índices B-Tree.
3. Simular um Deadlock
Preparação do Ambiente Primeiro, você precisa de duas tabelas para simular o deadlock. Vamos criar duas tabelas simples chamadas TABELA_001
e TABELA_002
:
CREATE TABLE TABELA_001(ID INT PRIMARY KEY, VALOR VARCHAR2(100));
CREATE TABLE TABELA_002(ID INT PRIMARY KEY, VALOR VARCHAR2(100));
INSERT INTO TABELA_001 (ID, VALOR) VALUES (1, 'Dona Florinda');
INSERT INTO TABELA_002 (ID, VALOR) VALUES (2, 'Professor Girafales');
COMMIT;
SYS@SESSAO_01> CREATE TABLE TABELA_001(ID INT PRIMARY KEY, VALOR VARCHAR2(100));
Table created.
SYS@SESSAO_01> CREATE TABLE TABELA_002(ID INT PRIMARY KEY, VALOR VARCHAR2(100));
Table created.
SYS@SESSAO_01> INSERT INTO TABELA_001 (ID, VALOR) VALUES (1, 'Dona Florinda');
1 row created.
SYS@SESSAO_01> INSERT INTO TABELA_002 (ID, VALOR) VALUES (2, 'Professor Girafales');
1 row created.
SYS@SESSAO_01> COMMIT;
Commit complete.
SYS@SESSAO_01>
Início da Simulação Abra duas sessões SQL diferentes, que representarão duas transações concorrentes.
Transação 1 Na primeira sessão (Transação 1), bloqueie um registro na TABELA
_001
-- Sessão 1
UPDATE TABELA_001 SET VALOR = 'Chaves' WHERE ID = 1;
SYS@SESSAO_01> UPDATE TABELA_001 SET VALOR = 'Chaves' WHERE ID = 1;
1 row updated.
SYS@SESSAO_01>
Não faça o commit ainda, para manter o bloqueio ativo.
Transação 2 Na segunda sessão (Transação 2), bloqueie um registro na TABELA_002
:
-- Sessão 2
UPDATE TABELA_002 SET VALOR = 'Dona Clotilde' WHERE ID = 2;
SYS@SESSAO_02> UPDATE TABELA_002 SET VALOR = 'Dona Clotilde' WHERE ID = 2;
1 row updated.
SYS@SESSAO_02>
Em seguida, tente atualizar o registro da TABELA_001
na segunda sessão
-- Sessão 2
UPDATE TABELA_001 SET VALOR = 'Seu Barriga' WHERE ID = 1;
SYS@SESSAO_02>
SYS@SESSAO_02> UPDATE TABELA_001 SET VALOR = 'Seu Barriga' WHERE ID = 1;
Esse comando não será executado, ele ficará em enq: TX – row lock contentetion aguardando o encerramento da transação da sessão 1.
Em seguida, tente atualizar o registro da TABELA_00
2 na primeira sessão
-- Sessão 1
UPDATE TABELA_002 SET VALOR = 'Jaiminho o Carteiro' WHERE ID = 2;
SYS@SESSAO_02>
SYS@SESSAO_01> UPDATE TABELA_002 SET VALOR = 'Jaiminho o Carteiro' WHERE ID = 2;
Neste ponto, cada sessão está esperando que a outra libere o bloqueio no recurso que deseja atualizar. Isso resulta em um deadlock. O Oracle detectará automaticamente essa situação e resolverá o deadlock fazendo rollback de uma das transações.
SYS@SESSAO_02> UPDATE TABELA_001 SET VALOR = 'Seu Barriga' WHERE ID = 1;
UPDATE TABELA_001 SET VALOR = 'Seu Barriga' WHERE ID = 1
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
SYS@SESSAO_02>
4. Estratégias de Resolução
Para resolver deadlocks, algumas estratégias podem ser aplicadas:
- Reordenar transações: Ajustar a lógica de transação para evitar aquisições de lock conflitantes.
- Aumentar alocação de recursos: Se o deadlock ocorrer devido a recursos insuficientes, considere aumentar os recursos alocados.
- Utilizar locks de nível de linha: Ao invés de locks de nível de tabela, para reduzir a granularidade do bloqueio.
5. Conclusão
Aproveitando que “ta vazi“, Deadlocks podem ser desafiadores, mas com a devida atenção e ferramentas adequadas, é possível identificar e resolver esses problemas, garantindo a continuidade e eficiência das operações do banco de dados Oracle.
🚀🚀🚀 Bóbó 🥎🥎🥎