PostgreSQL gleichzeitiges Inkrementieren des Zählers


9

Ich muss eine statistische Tabelle für ein Projekt führen, die aus einer Liste von Elementen und deren Verwendung besteht (denken Sie an eine Website, auf der Sie Seitenaufrufe zählen möchten). Jedes Mal, wenn ein Artikel instanziiert wird, muss ich die Verwendung des jeweiligen Artikels erhöhen.

Meine erste Implementierung ist:

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>';

Meine Bedenken beziehen sich auf Leistung und Parallelität. Der Aktualisierungsprozess wird von mehreren zehn (möglicherweise 80-120) Geräten instanziiert und kann mehrmals pro Sekunde erfolgen. Meine Fragen lauten daher:

1) Wird diese Methode die Parallelität bewahren? (Wenn also mehr als ein Gerät das Update "gleichzeitig" anfordert , wird jede Anforderung gezählt?)

2) Können Sie einen besten Weg vorschlagen, um das Ergebnis zu erzielen? Ich erwarte, dass die Updates geladen werden, während die Lesevorgänge mich viel häufiger treffen würden. Gibt es eine spezielle Funktion zum Inkrementieren von Werten? Ich schaue auf "Sequenz", bin mir aber nicht sicher, ob das der richtige Weg ist ...

Vielen Dank im Voraus für jeden Rat

Antworten:


5

Das zweite Update wartet auf das Festschreiben des vorherigen Updates in denselben Zeilen, zeigt dann jedoch den festgeschriebenen Wert an.

Angenommen, zwei Transaktionen aktualisieren gleichzeitig dieselbe Zeile mit dem Anfangswert 0

Zeittransaktion 1 T1-Wert Transaktion 2 T2-Wert
-------------------------------------------------- ------------
1 Update ... 1 0
2 1 Update .. "undefiniert"
                                (wartet) 
3 Commit 1 2
4 1 Commit 2
5 2 2 

"T1-Wert" und "T2-Wert" bezeichnet den Wert, den diese Transaktion sieht.

Wenn Sie sicherstellen möchten, dass Situationen usageerfasst werden, in denen "inkompatible" Änderungen vorliegen (z. B. wenn eine Transaktion die Spalte auf einen bestimmten Wert setzt, anstatt ihn nur zu erhöhen), können Sie alle Transaktionen in die Isolationsstufe "serialisierbar" versetzen. Dann müssen Sie sich jedoch auf die Fehlerbehandlung vorbereiten.

Aktualisierungen verschiedener Namen können ohne Wartezeit gleichzeitig ausgeführt werden (da unterschiedliche Zeilen betroffen sind).

SELECTs wird niemals blockiert, sondern sieht nur festgelegte Werte.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.