tobias_petry
Erfahrenes Mitglied
Nein, das Problem ist ja er kann immer alle Datensätze lesen und das Schreiben wird keine Fehlermeldung werfen sondern einfach warten, bis der Datensatz wieder freigegeben wird, und das ist der Knackpunkt.
Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
Hallo tobias_petri,
ich habe mit mysql noch nicht viel praktische Erfahrung sammeln dürfen,
aber mit anderen Datenbanken schon: z. B. Oracel.
Wenn in dem oben genannten Beispiel mit Auftragslisten gearbeitet wird, kann man das doch folgendermassen realisieren:
1. Lesen der zu bearbeitenden Daten ohne Lock (von mehreren Anwendern gleichzeitig)
2. Wenn ein Bearbeiter einen Datensatz aus seiner Liste bearbeiten will, werden
die Daten noch einmal von der Datenbank nachgelesen. Jetzt erfolgt ein
SELECT … FOR UPDATE mit dem eindeutigen Schlüssel. Dadurch sollte der Satz
für andere gesperrt werden. Ist der Satz schon bei jemand anders in Bearbeitung
erscheint die Meldung: Satz wird aktuell von jemand anders bearbeitet.
Wenn das nicht funktionert, stimmt die Dokumentation von mysql nicht:
SELECT … FROM … FOR UPDATE setzt exklusive Next-Key-Sperren auf alle Indexeinträge, die der Lesevorgang findet.
8.5.8.2. Lesevorgänge sperren
Unter manchen Umständen ist Konsistentes Lesen nicht wünschenswert. Angenommen, Sie wollen eine neue Zeile in die Tabelle kind einfügen und dabei sicherstellen, dass das Kind bereits Eltern in der Tabelle eltern hat.
Wenn Sie Konsistentes Lesen benutzen, um die Tabelle eltern zu lesen und in der Tat die Eltern des Kindes in der Tabelle sehen, können Sie dann sicher die Kind-Zeile zur Tabelle kind hinzufügen? Nein, denn es kann sein, dass zwischenzeitlich jemand anderes die Eltern-Zeile aus der Tabelle eltern gelöscht hat und Sie das nicht sehen.
Die Lösung besteht darin, das SELECT im Sperrmodus durchzuführen. LOCK IN SHARE MODE.
SELECT * FROM eltern WHERE NAME = 'Hinz' LOCK IN SHARE MODE;
Wenn Sie ein Lesen im Share-Modus durchführen, heißt das, dass die letzten verfügbaren Daten gelesen werden und eine Shared-Modus-Sperre auf die Zeile gesetzt wird, die gelesen wird. Wenn die letzten Daten zu einer noch nicht abgeschlossenen Transaktion eines anderen Benutzers gehören, wird gewartet, bis die Transaktion abgeschlossen (committed) ist. Eine Shared-Modus-Sperre verhindert, dass andere die Zeile aktualisieren oder löschen, die gerade gelesen wurde. Nachdem festgestellt wurde, dass die obige Anfrage die Eltern 'Hinr' zurückgibt, kann das Kind sicher zur Tabelle kind hinzugefügt und die Transaktion abgeschlossen werden. Dieses Beispiel zeigt, wie Sie in Ihren Applikations-Code referentielle Integrität integrieren können.
Sehen wir uns ein weiteres Beispiel an. Wir haben ein ganzzahliges Zählerfeld in einer Tabelle kind_codes, was benutzt wird, um jedem Kinde, das wir der Tabelle kind hinzufügen, eine eindeutige Kennung zuzuweisen. Es ist offensichtlich, dass Konsistentes Lesen oder Shared-Modus-Lesen kein geeignetes Mittel ist, um den aktuellen Wert des Zählers zu ermitteln, weil nämlich zwei Benutzer der Datenbank denselben Wert des Zählers sehen können und wir daher einen Fehler wegen doppelter Schlüsseleinträge erhalten, wenn wir zwei Kinder mit derselben Kennung in die Tabelle einfügen.
In diesem Fall gibt es zwei geeignete Möglichkeiten, das Lesen und Heraufzählen des Zählers zu implementieren: (1) Zuerst den Zähler um eins erhöhen und erst danach lesen. (2) Zuerst den Zähler im Sperr-Modus FOR UPDATE lesen und danach heraufzählen:
SELECT COUNTER_FIELD FROM kind_codes FOR UPDATE;
UPDATE kind_codes SET COUNTER_FIELD = COUNTER_FIELD + 1;
SELECT ... FOR UPDATE liest die letzten verfügbaren Daten und setzt exklusive Sperren auf jede Zeile, die es liest. Daher setzt es dieselben Sperren, die ein gesuchtes SQL-UPDATE auf die Zeilen setzen würde.