tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
12
ZUGRIFFE
1314
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    marcel_m marcel_m ist offline Mitglied Silber
    Registriert seit
    Jul 2006
    Beiträge
    80
    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
     

  2. #2
    Avatar von tobias_petry
    tobias_petry tobias_petry ist offline Mitglied Brokat
    Registriert seit
    Nov 2003
    Beiträge
    284
    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 :
    1
    
    UPDATE `tabelle` SET `flag`=1 WHERE `flag`=0
     

  3. #3
    marcel_m marcel_m ist offline Mitglied Silber
    Registriert seit
    Jul 2006
    Beiträge
    80
    Zitat Zitat von tobias_petry Beitrag anzeigen
    Ist diese Datenbank nun in MySQL oder InnoDB entwickelt?
    Und falls es MySQL ist, welches Tabellenformat nutzt ihr?
    Vielen Dank für deine Antwort!
    Wir benutzen MySQL und als Tabellenformat InnoDB
     

  4. #4
    Avatar von tobias_petry
    tobias_petry tobias_petry ist offline Mitglied Brokat
    Registriert seit
    Nov 2003
    Beiträge
    284
    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.
     
    "If you give someone a program, you will frustrate them for a day
    but if you teach them how to program, you will frustrate them for a lifetime."

  5. #5
    marcel_m marcel_m ist offline Mitglied Silber
    Registriert seit
    Jul 2006
    Beiträge
    80
    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
     

  6. #6
    BLOEBAUM BLOEBAUM ist offline Mitglied Gold
    Registriert seit
    Sep 2005
    Ort
    Kreis Herford
    Beiträge
    114
    Hallo Marcel,

    schau dir mal die Inhalte der folgenden Links an, dann wird dir dein Problem
    etwas klarer erscheinen.

    http://dev.mysql.com/doc/refman/5.1/...isolation.html

    http://dev.mysql.com/doc/refman/5.1/...locks-set.html

    Zu deinem Thema: "ewig gesperrt bleiben":
    http://dev.mysql.com/doc/refman/5.1/...-rollback.html

    Gruß

    Harald
     

  7. #7
    Avatar von tobias_petry
    tobias_petry tobias_petry ist offline Mitglied Brokat
    Registriert seit
    Nov 2003
    Beiträge
    284
    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.
     
    "If you give someone a program, you will frustrate them for a day
    but if you teach them how to program, you will frustrate them for a lifetime."

  8. #8
    BLOEBAUM BLOEBAUM ist offline Mitglied Gold
    Registriert seit
    Sep 2005
    Ort
    Kreis Herford
    Beiträge
    114
    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.
     

  9. #9
    Avatar von tobias_petry
    tobias_petry tobias_petry ist offline Mitglied Brokat
    Registriert seit
    Nov 2003
    Beiträge
    284
    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.
     
    "If you give someone a program, you will frustrate them for a day
    but if you teach them how to program, you will frustrate them for a lifetime."

  10. #10
    BLOEBAUM BLOEBAUM ist offline Mitglied Gold
    Registriert seit
    Sep 2005
    Ort
    Kreis Herford
    Beiträge
    114
    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!
     

  11. #11
    Avatar von tobias_petry
    tobias_petry tobias_petry ist offline Mitglied Brokat
    Registriert seit
    Nov 2003
    Beiträge
    284
    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.
     
    "If you give someone a program, you will frustrate them for a day
    but if you teach them how to program, you will frustrate them for a lifetime."

  12. #12
    marcel_m marcel_m ist offline Mitglied Silber
    Registriert seit
    Jul 2006
    Beiträge
    80
    Ich danke euch für eure vielen Antworten!
    Gelöst scheint das Problem wohl nicht ganz zu sein.
    Ich werde eine provisorische Lösung vornehmen:
    Ich füge eine Spalte namens author o. ä. hinzu, die den Benutzernamen des Verwalters beinhaltet. Nur dieser kann dann noch den Auftrag einsehen, editieren, ... .
    Die Auftragsverwaltung läuft dann halt ähnlich wie beim eMail abholen: man gibt bekommt zwischen 3-7 neue Aufträge per klick hinzu, um die man sich kümmeren muss... wenn die abgearbeitet sind, fordert man halt die nächsten an ...

    Ich lasse dieses Topic trotzdem noch offen, da eine Lösung bisher ja noch nicht gefunden ist und ich das Programm noch nicht abgeben musss. Sollte sich die Lösung noch finden, kann ich versuchen so weit wie möglich diese im Programm zu berücksichtigen...

    Vielen Dank noch einmal,

    Marcel
     

  13. #13
    Kniffel Kniffel ist offline Grünschnabel
    Registriert seit
    Mar 2007
    Beiträge
    1
    Zitat Zitat von BLOEBAUM Beitrag anzeigen
    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.
    Im Grunde genommen ist dieser Ansatz schon weitestgehend richtig, allerdings liefert selbst SELECT ... FOR UPDATE nur einen Schnappschuss der Datenbank, um wirklich eine Lesesperre zu erhalten müsste man laut MySQL-4.1-Refernzhandbuch den Befehl SELECT ... LOCK IN SHARE MODE verwenden.

    Hier einfach mal der Abschnitt aus dem Referenzhandbuch:
    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.
    Nur als Hinweis selbst wenn man ein Flag verwendet, kann man nicht sicher sein, dass ein anderer User in der Millisekunde vor dem Flag setzen den Datensatz geändert hat.

    Wenn Du mehr wissen willst lad Dir doch einfach das MySQL-Referenzhandbuch herunter und lies Dir den Abschnitt "8.5. InnoDB-Tabellen" durch.

    Sehr informativ ist auch diese Seite http://www.innodb.com

    Beste Grüße
     

Ähnliche Themen

  1. MySQL Transaktionsübegreifendes Locking?
    Von Test-Tomato im Forum Relationale Datenbanksysteme
    Antworten: 0
    Letzter Beitrag: 11.01.11, 09:59
  2. Annotation für Pessimistisches Locking
    Von AliB im Forum Enterprise Java (JEE, J2EE, Spring & Co.)
    Antworten: 0
    Letzter Beitrag: 08.10.07, 13:40
  3. [MySQL] row-level locking
    Von ZeroEnna im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 23.09.05, 16:37
  4. [ORACLE] Demo: Locking Verfahren
    Von Exceptionfault im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 23.08.05, 22:58
  5. Eclipse Problem mit file locking
    Von SuperSonik im Forum Java
    Antworten: 4
    Letzter Beitrag: 09.08.04, 12:57