In einer Tabelle , wobei jede Zeile einen Zähler hat (nur ein ganzzahliger Wert ist ), muß ich den Stromwert zu erhalten und zu erhöhen es zugleich .
Eigentlich möchte ich das tun:
SELECT counter FROM table WHERE id=123
UPDATE table SET counter=counter+1 WHERE id=123
Dies als zwei Abfragen zu tun ist jedoch offensichtlich nicht threadsicher: Mehrere Prozesse, die dasselbe (in derselben Zeile) ausführen, erhalten möglicherweise denselben Zählerwert. Ich brauche sie alle einzigartig zu sein, so dass jeder Prozess die bekommen würde tatsächlichen aktuellen Wert und erhöhen sie um eins.
Ich kann mir eine Konstruktion vorstellen, bei der ich eine manuelle Sperre pro Zeile implementiere, aber ich frage mich, ob es einen einfacheren Weg gibt, dies zu tun.
Antworten:
Die Update-Anweisungen funktionieren einwandfrei ohne die Auswahl zuvor! Da einzelne Anweisungen per Definition sicher sind, führt selbst zwei gleichzeitig ausgeführte UPDATE-Abfragen dazu, dass die Zeile zweimal erhöht wird.
Wenn Sie tatsächlich den Wert für Ihr PHP-Skript auswählen, etwas damit tun und später diesen genauen Zählerwert aktualisieren möchten, können Sie Folgendes tun:
Dadurch wird eine neue Transaktion gestartet, dann werden die zu aktualisierenden Zeilen ausgewählt und ausschließlich gesperrt. Sie können diese dann sicher aktualisieren, ohne sich Sorgen machen zu müssen, dass andere Clients ihren Inhalt ändern oder sogar auf die gesperrten Zeilen zugreifen. Schließlich müssen Sie Ihre Änderungen festschreiben.
Sie sollten auch etwas über Isolationsstufen lesen . Sie möchten wahrscheinlich keinen Wert wie
READ UNCOMMITTED
Isolationsstufe. Alles andere sollte für diesen Anwendungsfall in Ordnung sein.quelle
UPDATE table SET counter = counter + 1
ausreichend atomar ist? Benötigen Sie noch die dazugehörigen Transaktionsanweisungen?FOR UPDATE
Transaktionen verwenden, unterscheidet sich der ausgewählte Wert möglicherweise von dem Wert, der in der Aktualisierungsabfrage verwendet wurde. Meine Kombination von Abfragen sperrt die Zeile, sobald der Wert ausgewählt ist, und stellt daher sicher, dass dieser genaue Zählerwert in der Aktualisierungsabfrage verwendet wird.