Record Locking Problem

marcel_m

Mitglied
Hallo zusammen,

ich bin relativ unerfahren was MySQL angeht. Im Rahmen eines Seminarkurses den ich am Gymnasium mache, programmiere ich mit meinem Schulkameraden ein Warenwirtschaftssystem unter Java.

Wir haben uns auf MySQL mit InnoDB geeinigt.
Unser Problem ist, dass wir Datensätzen sperren müssen, damit verschiedene Benutzer unseres Programm nicht gleichzeitig einen Auftrag abarbeiten.
Obwohl unser Programm Multiuser fähig ist, arbeiten sämtlicheBenutzer unseres Programms über einen MySQL Benutzeraccount. Ist es dann überhaupt noch möglich Datensätze zu sperren, denn MySQL sieht die verschiedenen Benutzer unseres Systems ja als einen (MySQL) Benutzer an...

Generell weiß ich zwar vom Begriff Record locking, aber nicht, wie ich dieses unter MySQL zu verwenden habe... hat hier jemand vielleicht generelle Hinweise, Links, ...


Ich bedanke mich schon einmal im Voraus....



Marcel
 
Ist diese Datenbank nun in MySQL oder InnoDB entwickelt?
Und falls es MySQL ist, welches Tabellenformat nutzt ihr?

In MySQL ist es nur möglich eine gesamte Tabelle zu Sperren, dafür stellt MySQL die LOCK TABLE-Syntax zur Verfügung.
Es wird euch nur die Möglichkeit bleiben eine gesamte Tabelle zu sperren oder zusammen mit Java einen eigenen Locking-Mechanismus zu erstellen, der mit Flags arbeitet.
Wichtig ist, dass ihr bei dem setzen des Flasg drauf achtet, dass nicht gerade schon der Flag gesetzt wurde, also folgendermaßen:
Code:
UPDATE `tabelle` SET `flag`=1 WHERE `flag`=0
 
also fällt LOCK TABLES schonmal weg, da dies in InnoDB nicht verwendet werden soll.
Ich weiß nicht in wieweit ihr den Zugriff sperren müsst, aber vllt reicht ja schon die Isolation von InnoDB (Bestandteil der ACID) ansonsten eben das genannte System mit Flags.
By the way, ist das WHERE-Konstrukt nicht zum Spaß da, sondern zur Verhinderung von Race Conditions / Race Hazards.
 
Das Problem, das ich habe tritt an mehreren "Stellen" auf.
Zum Beispiel wird eine Auftragsliste, die von Mitarbeitern abgearbeitet wird, in einer Tabelle festgehalten. Problematik ist eben hier, dass nicht zwei Mitarbeiter den selben Auftrag zur gleichen Zeit abarbeiten und somit den Auftrag doppelt bearbeiten.

Wenn ich hier mit Flags arbeiten würde, wäre der Datensatz bei einem PC Absturz seitens des Bearbeiters für immer und ewig gesperrt (oder kann man das mit Rollbacks lösen?).

An dieser Stelle vielen Dank für deine Antworten,

Marcel
 
Bloebaum, dass Problem der Isolation bei InnoDB ist leider, dass nun doch 2 User den gleichen Datensatz bearbeiten können, weil ihre beiden Transaktionen getrennt voneinander laufen, hatte ein ähnliches Problem und es kam auf Grund vieler anfragen zu Race Conditions.

Marcel, es ist etwas kritisch, weil sobald du eine Transaktion startest, dass bei einem Systemabsturz alles rückgängig gemacht wird (Rollback) wird der User in seiner Isolation keine Änderungen in der DB vermerken und andere User können den Auftrag auch annehmen.
Die einzige Möglichkeit wird darin bestehen, dem Flag weitere Zustandsinformationen hinzuzufügen, damit ein Lock durch einen Flag auf einen Datensatz erkannt werden kann, dessen Rechner diesen Datensatz gar nicht mehr bearbeitet.
Das Problem bei den Isolationsebenen von InnoDB ist, dass du noch unvollendete Transaktionen hast, die sich noch nicht in der Datenbank befinden, deshalb wird dir die Datenbank dies nicht abnehmen können und du musst es selbst lösen.
Eine weiter Lösung zu dem Flag-System wäre natürlich ein zentraler Server, der die Datensätze verteilt, und dementsprechend natürlich auch Datensätze nur einmal zuteilen kann und bei einem Systemabsturz einfach seine Änderungen revidiert.
 
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.
 
neija das Problem an einem SELECT .... FOR UPDATE ist, dass der Datensatz einen Exclusiv-Lock erhält ja, aber nur fürs Schreiben, er kann immernoch von allen anderen Transaktionen gelesen werden.
 
Dann sollte das Problem doch genau so lösbar sein wie ich es geschrieben habe.
Wenn jemand in seiner aktuellen Auftragsliste die falschen Daten hat, weil in der Zwischenzeit ein anderer Benutzer den Satz geändert hat, kann man diesem Benutzer die Information doch zukommen lassen, sobald er versuchte den Satz zu ändert:

Meldung: Der Auftrag wurde in der Zwischenzeit bereits geändert, bitte Änderungen beachten!
 

Neue Beiträge

Zurück