Eu tive um problema de impasse que foi fácil de corrigir alterando a lógica do aplicativo, mas tive a impressão de que o Oracle se comportaria de maneira diferente e o impasse nunca aconteceria. Eu tenho duas tabelas, por exemplo
table1( table1_id (PK), num1, num2);
table2(table2_id(PK), table1_id(FK to table1,indexed), low_cardinality_column, num3, num4);
Table2 também possui um after update
gatilho de nível de linha que atualiza table1.num
( table1.num1 = table1.num1 + :NEW.num3 where table1.table1_id = :NEW.table1_id
).
O primeiro processo é executado UPDATE table2 set num3 =1 where low_cardinality_column =:bind_var
(sem índice em low_cardinality_column
, normalmente alguns milhares de registros afetados).
O segundo processo atualiza table2 e table1 em uma transação com
UPDATE table2
SET num4 = :bind_var4
WHERE table2_id = :bind_var_id
RETURNING table1_id INTO :out_var
UPDATE table1
SET num2 = :new_num2_val
WHERE table1_id = :out_var
O rastreamento mostrou alguns impasses entre esses 2 processos, se eles forem executados ao mesmo tempo, e estou um pouco confuso com isso. Entendo que impasses devem ter ocorrido no caso de o segundo processo atualizar as tabelas na ordem inversa ( table1
, então table2
), mas, neste caso específico, pensei que o mecanismo não iniciaria a atualização até obter o bloqueio RX em cada registro que deve ser atualizado (portanto um processo esperaria que outro terminasse). Se não for garantido, a explicação do impasse é óbvia: o Processo 1 bloqueia os registros em ordem indefinida e o Processo 2 atualizou a linha table2
ainda não bloqueada e tenta atualizar a linha table1
já atualizada pelo Processo 1. No caso do SQLServer I teria 100% de certeza de que é esse o caso, mas ainda sou muito novo no Oracle ...
Gostaria de saber se alguém poderia esclarecer a questão. Obrigada. Eu uso 10g se isso importa.
Você está certo: o processo 2 começa com a atualização na Tabela2, mas encontra um impasse com a atualização na Tabela1 porque a linha está sendo atualizada pelo processo 1 (e ainda não confirmada).
Sua suposição de que o banco de dados "sabe" que encontrará um impasse no processo 2 e negará a transação está errada. O banco de dados desconhece declarações futuras em uma transação, portanto, não pode evitar um impasse.