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

No PostgreSQL, vários UPDATEs para diferentes linhas na mesma tabela têm bloqueios conflitantes?


UPDATE bloqueia a linha, então você não precisa bloqueá-la primeiro. Se você tentar UPDATE sobreposição de conjuntos de linhas simultaneamente, o segundo UPDATE aguardará a primeira transação confirmar ou reverter.

O grande problema com sua abordagem - além do fato de que UPDATE não tem um LIMIT cláusula - é que vários trabalhadores tentarão pegar as mesmas linhas. Aqui está o que acontece:
  • worker1:filtra a tabela para encontrar 200 linhas e as bloqueia
  • worker1:inicia a atualização das linhas
  • worker2:filtra a tabela para encontrar 200 linhas
  • worker2:tenta iniciar a atualização de linhas, mas selecionou as mesmas linhas que worker1 para bloquear no bloqueio de worker1
  • worker1:conclui a atualização das linhas
  • worker2:após a liberação do bloqueio, verifica novamente a condição WHERE e descobre que nenhuma das linhas corresponde mais porque worker1 as atualizou. Atualiza zero linhas.

... e repita!

Você precisa:
  • Tenha uma fila central distribuindo as linhas de uma maneira segura de simultaneidade; ou
  • Atribuir aos funcionários intervalos de IDs sem sobreposição para trabalhar

Quanto a LIMIT - você pode usar WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id) - mas você teria o mesmo problema com os dois trabalhadores escolhendo o mesmo conjunto de linhas para atualizar.