PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Dans PostgreSQL, plusieurs mises à jour vers différentes lignes de la même table ont-elles des verrous en conflit ?

UPDATE verrouille la ligne, vous n'avez donc pas besoin de la verrouiller au préalable. Si vous essayez de UPDATE des ensembles de lignes qui se chevauchent simultanément, le second UPDATE attendra que la première transaction soit validée ou annulée.

Le gros problème avec votre approche - autre que le fait que UPDATE n'a pas de LIMIT clause - est que plusieurs travailleurs essaieront tous de saisir les mêmes lignes. Voici ce qui se passe :

  • worker1 :filtre la table pour trouver 200 lignes et les verrouille
  • worker1 :commence la mise à jour des lignes
  • worker2 :filtre le tableau pour trouver 200 lignes
  • worker2 :essaie de démarrer la mise à jour des lignes, mais a sélectionné les mêmes lignes que worker1, il se bloque donc sur le verrou de worker1
  • worker1 :Termine la mise à jour des lignes
  • worker2 :après le déverrouillage, revérifie la condition WHERE et découvre qu'aucune des lignes ne correspond plus car worker1 les a mises à jour. Met à jour zéro ligne.

... et répétez !

Vous devez soit :

  • Avoir une file d'attente centrale distribuer les lignes d'une manière appropriée et sécurisée ; ou
  • Attribuer aux collaborateurs des plages d'ID qui ne se chevauchent pas sur lesquelles travailler

Comme pour LIMIT - vous pouvez utiliser WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id) - mais vous auriez le même problème si les deux travailleurs choisissaient le même ensemble de lignes à mettre à jour.