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.