PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PSQLException e problema de bloqueio quando o gatilho adicionado na tabela


Problema interessante. Este é o meu melhor palpite. Eu testei nada disso.

De um modo geral, a suposição educada do postgres sobre o efeito que as declarações terão nos dados não se estende à lógica do gatilho. Ao executar a segunda instrução, o postgres vê a restrição de chave estrangeira e sabe que deve verificar se o valor que está sendo atribuído (inserido) é válido, ou seja, se representa uma chave válida na tabela estrangeira. É possível, por má prática, que o gatilho possa afetar a validade da chave estrangeira que está sendo proposta (por exemplo, se o gatilho excluir registros).

(caso 1) Se não houver nenhum trigger, então ele pode olhar para os dados (tanto pré-commit quanto preparado para commit) e decidir se o valor proposto é garantido como válido. (caso 2) Se não houver restrição FK, então o trigger não pode impactar na validade da inserção, então ela é permitida. (caso 3) Se você omitir o detail_id=null , não há alteração na atualização para que o gatilho não seja acionado, portanto sua presença é irrelevante.

Eu tento evitar tanto as restrições FK quanto os gatilhos sempre que possível. É melhor, na minha opinião, deixar o banco de dados acidentalmente conter dados parcialmente incorretos do que deixá-lo travar completamente, como você está vendo aqui. Eu descartaria todas as restrições e gatilhos FK e forçaria todas as operações de atualização e inserção a operar por meio de funções armazenadas, que executam a validação dentro de um bloqueio de início/confirmação e lidam com tentativas de inserção/atualização incorretas/inválidas de forma adequada e imediata, em vez de forçar o postgres a espere o comando 1 confirmar antes de decidir se o comando 2 é permitido.

Editar: veja esta pergunta

Editar 2: A coisa mais próxima que posso encontrar da documentação oficial sobre o tempo dos gatilhos em relação à verificação de restrições é o documentos de gatilhos

Isso é um pouco obscuro, se o gatilho ocorrer antes da verificação de restrição se aplicar à verificação de restrição de outras transações. Seja qual for o caso, esse problema é um bug ou está mal documentado.