sql >> Database >  >> RDS >> PostgreSQL

postgresql-impasse

Dit zijn twee opmerkingen die worden ingevoegd met dezelfde content_id. Door alleen de opmerking in te voegen, wordt een SHARE-vergrendeling op de inhoudsrij opgeheven, om te voorkomen dat een andere transactie die rij verwijdert totdat de eerste transactie is voltooid.

De trigger gaat dan echter door met het upgraden van het slot naar EXCLUSIEF, en dit kan worden geblokkeerd door een gelijktijdige transactie die hetzelfde proces uitvoert. Overweeg de volgende reeks gebeurtenissen:

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)

Dus impasse.

Een oplossing is om onmiddellijk neem een ​​exclusief slot op de inhoudsrij vóór het invoegen van de opmerking. d.w.z.

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

Een andere oplossing is simpelweg om dit patroon van "gecachte tellingen" volledig te vermijden, behalve waar je kunt bewijzen dat het nodig is voor de prestaties. Als dat het geval is, overweeg dan om het aantal in de cache ergens anders te bewaren dan de inhoudstabel, bijv. een speciale tafel voor de toonbank. Dat zal ook het updateverkeer naar de inhoudstabel verminderen telkens wanneer een opmerking wordt toegevoegd. Of misschien gewoon opnieuw de telling selecteren en memcached gebruiken in de applicatie. Je kunt er niet omheen dat waar je deze telling in de cache ook opslaat een knelpunt zal zijn, het veilig moet worden bijgewerkt.




  1. Waarde voor Autoincrement ophalen na INSERT-query in MySQL

  2. Opgeslagen procedure blijft schijnbaar zonder uitleg hangen

  3. PostgreSQL-fout:kon geen gegevens van de client ontvangen:er is een bewerking geprobeerd op iets dat geen socket is

  4. Hoe documenteert u uw databasecode om afhankelijkheden tussen databaseobjecten te zien?