PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

stallo postgresql

Questi sono due commenti inseriti con lo stesso content_id. Il semplice inserimento del commento eliminerà un blocco SHARE sulla riga del contenuto, in modo da interrompere un'altra transazione eliminando quella riga fino al completamento della prima transazione.

Tuttavia, il trigger passa quindi all'aggiornamento del blocco a ESCLUSIVO e questo può essere bloccato da una transazione simultanea che esegue lo stesso processo. Considera la seguente sequenza di eventi:

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)

Quindi, stallo.

Una soluzione è immediatamente prendi un blocco esclusivo sulla riga del contenuto prima inserendo il commento. cioè

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

Un'altra soluzione consiste semplicemente nell'evitare completamente questo modello di "conteggi nella cache", tranne quando è possibile dimostrare che è necessario per le prestazioni. In tal caso, considera di mantenere il conteggio memorizzato nella cache in un luogo diverso dalla tabella dei contenuti, ad es. un tavolo dedicato per il bancone. Ciò ridurrà anche il traffico di aggiornamento verso la tabella dei contenuti ogni volta che viene aggiunto un commento. O forse semplicemente riselezionare il conteggio e utilizzare memcached nell'applicazione. Non c'è modo di aggirare il fatto che ovunque memorizzi questo conteggio memorizzato nella cache sarà un punto di strozzatura, deve essere aggiornato in modo sicuro.