Incremento simultaneo del contatore PostgreSQL


9

Devo mantenere una tabella statistica per un progetto, composta da un elenco di elementi e dal loro utilizzo (pensa a qualcosa come un sito Web in cui vorresti contare le visualizzazioni di pagina). Ogni volta che viene istanziato un articolo, devo incrementare l'utilizzo dell'articolo specifico.

La mia prima implementazione è:

statistics(
  id      integer NOT NULL,
  name    character varying(255) NOT NULL,
  usage   integer NOT NULL DEFAULT 0,
);


UPDATE statistics 
  SET usage = usage + 1
WHERE name = '<name>';

Le mie preoccupazioni riguardano prestazioni e concorrenza. Il processo di aggiornamento verrà istanziato da diverse decine (forse 80-120) dispositivi e potrebbe verificarsi più volte al secondo, quindi le mie domande sono:

1) questo metodo conserverà la concorrenza? (ovvero se più dispositivi richiedono l'aggiornamento "contemporaneamente", verrà conteggiata ogni richiesta?)

2) puoi suggerire un modo migliore per ottenere il risultato? Mi aspetto di avere un carico nello scrivere gli aggiornamenti, mentre le letture mi farebbero molto più frequentemente. Esiste una funzione specifica per incrementare i valori? Sto guardando "sequenza" ma non sono sicuro che sia il modo giusto ...

Grazie mille in anticipo per qualsiasi consiglio

Risposte:


5

Il secondo aggiornamento aspetterebbe il commit dell'aggiornamento precedente sulle stesse righe, ma vedrà quindi il valore di commit.

Supponiamo che due transazioni simultanee aggiornino la stessa riga con un valore iniziale pari a 0

Valore Transazione temporale 1 T1 Valore Transazione 2 T2
-------------------------------------------------- ------------
1 aggiornamento ... 1 0
2 1 aggiornamento .. "undefined"
                                (attese) 
3 commit 1 2
4 1 commit 2
5 2 2 

"Valore T1" e "Valore T2" ​​indica il valore visualizzato da quella transazione.

Se si desidera assicurarsi di rilevare situazioni in cui vi sono modifiche "incompatibili" (ad esempio, una transazione che imposta la usagecolonna su un valore specifico, anziché semplicemente incrementarla), è possibile inserire tutte le transazioni nel livello di isolamento "serializzabile". Ma dovrai prepararti per la gestione degli errori.

Gli aggiornamenti a nomi diversi possono essere eseguiti contemporaneamente senza attese (poiché sono interessate righe diverse).

SELECTs non verrà mai bloccato ma vedrà solo i valori inseriti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.