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

blocage postgresql

Ce sont deux commentaires insérés avec le même content_id. La simple insertion du commentaire supprimera un verrou SHARE sur la ligne de contenu, afin d'empêcher une autre transaction de supprimer cette ligne jusqu'à ce que la première transaction soit terminée.

Cependant, le déclencheur passe ensuite à la mise à niveau du verrou vers EXCLUSIF, et cela peut être bloqué par une transaction simultanée exécutant le même processus. Considérez la séquence d'événements suivante :

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)

Donc, impasse.

Une solution consiste à immédiatement prendre un verrou exclusif sur la ligne de contenu avant en insérant le commentaire. c'est-à-dire

SELECT 1 FROM content WHERE content.id = 935967 FOR UPDATE
INSERT INTO comment(.....)

Une autre solution consiste simplement à éviter complètement ce modèle de "comptes mis en cache", sauf si vous pouvez prouver qu'il est nécessaire pour les performances. Si tel est le cas, envisagez de conserver le décompte mis en cache ailleurs que dans la table de contenu, par exemple. une table dédiée pour le comptoir. Cela réduira également le trafic de mise à jour vers la table de contenu chaque fois qu'un commentaire est ajouté. Ou peut-être simplement resélectionner le nombre et utiliser memcached dans l'application. Il est indéniable que, quel que soit l'endroit où vous stockez ce décompte mis en cache, il s'agira d'un point d'étranglement, il doit être mis à jour en toute sécurité.