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

impasse postgresql


Estes são dois comentários sendo inseridos com o mesmo content_id. A simples inserção do comentário removerá um bloqueio SHARE na linha de conteúdo, para impedir que outra transação exclua essa linha até que a primeira transação seja concluída.

No entanto, o gatilho passa a atualizar o bloqueio para EXCLUSIVE, e isso pode ser bloqueado por uma transação simultânea executando o mesmo processo. Considere a seguinte sequência de eventos:
Txn 2754                      Txn 2053
Insert Comment
                              Insert Comment
Lock Content#935967 SHARE
  (performed by fkey)
                              Lock Content#935967 SHARE
                                (performed by fkey)
Trigger
Lock Content#935967 EXCLUSIVE
(blocks on 2053's share lock)
                              Trigger
                              Lock Content#935967 EXCLUSIVE
                              (blocks on 2754's share lock)

Então, impasse.

Uma solução é imediatamente faça um bloqueio exclusivo na linha de conteúdo antes inserindo o comentário. ou seja
SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)

Outra solução é simplesmente evitar completamente esse padrão de "contagens em cache", exceto quando você puder provar que é necessário para o desempenho. Em caso afirmativo, considere manter a contagem em cache em outro lugar que não seja a tabela de conteúdo-- ex. uma mesa dedicada para o balcão. Isso também reduzirá o tráfego de atualização para a tabela de conteúdo sempre que um comentário for adicionado. Ou talvez apenas selecione novamente a contagem e use o memcached no aplicativo. Não há como contornar o fato de que onde quer que você armazene essa contagem em cache será um ponto de estrangulamento, ela deve ser atualizada com segurança.