heinetz: LOCK TABLES?

Hallo Forum,

ich habe vor langer Zeit mal eine Anwendung programmiert, bei der über ein einfaches Frontend mit HTML-Formularen nahezu sämtliche Inhalte einer MySQL-DB editiert werden können. Dieses Frontend wird von so einigen Benutzern bedient und ich habe mir damals keine Gedanken darüber gemacht, dass die zeitgleich auf die DB zugreifen könnten. Darüber hinaus ist nicht einfach so, dass ein Datensatz nur:

1. per SELECT ausgelesen
2. dann im <form> angezeigt
3. und dann mit einem UPDATE

... überschrieben wird, sondern nach dem Absenden des Formulars passiert in der DB einiges.
Sprich die Prozedur besteht darin, dass diverse MySQL-Statement nacheinander ausgeführt werden, weil mehrere voneinander abhängige Datensätze manipuliert werden müssen.

Nun ist es mehrfach vorgekommen, dass nach oder während der Benutzung des Systems Datensätze verschwunden waren und dem Anschein nach immer dann, wenn mehrere Benutzer gliechzeitig mit dem System arbeiteten, was ich nur so interpretieren kann, dass die Datenbankinhalte durch einen anderen Zugriff geändert werden, während die eben beschriebene Prozedur abgearbeitet wird.

Nun würde ich am liebsten erstmal irgendwie nachvollziehen, in welchem Moment sich was genau in die Quere kommt. Dazu könnte man sicher jedes abgesetzte MySQL-Statement zusammen mit der SESSION-ID und einem Timestamp loggen. Ich kann mir aber vorstellen, dass die Programmierung dieser Loggerei zum Einen aber vor Allem die Auswertung, wenn dann eine Fehler aufgetreten ist zum Anderen so aufwändig ist, dass es einfacher ist, MySQL-Tabellen zu sperren. Ich habe allerdings noch nie mit LOCK TABLES gearbeitet. Muss ich irgendwas bedenken?

beste gruesse,
heinetz

  1. Tach!

    1. per SELECT ausgelesen
    2. dann im <form> angezeigt
    3. und dann mit einem UPDATE

    Das sind zwei getrennte Datenbankaktionen. Die bekommst du nicht mit MySQLs Mitteln atomar, weil nach dem Select-Request die MySQL-Verbindung abgebaut wird und zum Update eine neue erstellt wird. Ein LOCK TABLES ist aber an die Session/MySQL-Verbindung gebunden. Wenn du für diesen mehrstufigen Vorgang ein Ändern des Datensatzes von anderen Prozessen verhindern möchtest, musst du dir selbst etwas ausdenken. Das kann zum Beispiel ein spezielles Feld in der Tabelle sein, das mit einer Sperrinformation belegt wird, oder auch eine eigene Tabelle, in der diese Sperrungen hinterlegt werden.

    Sprich die Prozedur besteht darin, dass diverse MySQL-Statement nacheinander ausgeführt werden, weil mehrere voneinander abhängige Datensätze manipuliert werden müssen.

    Warum ist das nicht in einer Transaction gekapselt?

    Nun würde ich am liebsten erstmal irgendwie nachvollziehen, in welchem Moment sich was genau in die Quere kommt.

    Das halte ich für unnötig. Es bringt keinen wirklichen Erkenntnisgewinn.

    Ich habe allerdings noch nie mit LOCK TABLES gearbeitet. Muss ich irgendwas bedenken?

    Ja, du solltest die Eigenschaften von Table-Locking und Transactions im Handbuch lesen und dann schauen, wie sie auf dein Projekt passen.

    dedlfix.

    1. Jo,

      Recht hast Du. Gucken wie's geht und dann machen.
      vielen Dank für's Zuhören ;)

      heinetz

    2. Ich musste über sowas auch schon detaillierter nachdenken.

      Eine einfache Möglichkeit wäre, das Datum der letzten Änderung zu speichern und evtl. noch die Person die das geändert hat.
      Dann könnte man das Änderungsdatum abgleichen (müsste im Formular als verstecktes Feld stehen damit es bekannt bleibt). Wenn der Eintrag beim Speichern inzwischen geändert wurde, kriegt der Benutzer eine Meldung: Die Daten wurden zwischenzeitlich von xy schon geändert, willst du diese Änderungen wirklich nochmal überschreiben?
      Dann kann man sich erkundigen was derjenige da gemacht hat und ob diese Infos inzwischen aktueller sind als die eigenen.

      Was hier sinnvoll ist hängt stark von den Gegebenheiten ab.
      Wenn die Nutzer *eigentlich* wissen sollten was sie tun und eine parallele Bearbeitung aufgrund der Situation praktisch schon ausgeschlossen ist (z.B. weil man dazu ein Stück Ware in die Hand nehmen muss, was nicht mehrere Personen zur gleichen Zeit können), wäre eine einfache Abfrage ausreichend. Um etwa die Reservierung eines Platzes im Flugzeug gegen weltweite parallele Bearbeitungen zu schützen braucht man dann schon andere Maßnahmen.

      1. Hallo,

        Eine einfache Möglichkeit wäre, das Datum der letzten Änderung zu speichern und evtl. noch die Person die das geändert hat.
        Dann könnte man das Änderungsdatum abgleichen (müsste im Formular als verstecktes Feld stehen damit es bekannt bleibt). Wenn der Eintrag beim Speichern inzwischen geändert wurde, kriegt der Benutzer eine Meldung: Die Daten wurden zwischenzeitlich von xy schon geändert, willst du diese Änderungen wirklich nochmal überschreiben?
        Dann kann man sich erkundigen was derjenige da gemacht hat und ob diese Infos inzwischen aktueller sind als die eigenen.

        Aus meiner Sicht zu spät. Sinnvoller wäre es beim Beginn des Bearbeitens eine Meldung auszugeben: Benutzer xy hat vor z Minuten mit der Bearbeitung der Seite begonnen und noch nicht beendet. Wollen Sie die Seite trotzdem bearbeiten? Dann kann man bevor man sich viel Arbeit macht mit demjenigen abklären, was er macht.

        vg ichbinich

        --
        Kleiner Tipp:
        Tofu schmeckt am besten, wenn man es kurz vor dem Servieren durch ein saftiges Steak ersetzt...
        1. Aus meiner Sicht zu spät.

          Spät ist es. Aber nicht wirklich *zu* spät um Chaos zu vermeiden.
          Es kommt natürlich drauf an wie häufig eine Kollision zweier Bearbeiter ist und wie aufwendig die aufgelöst werden muss. Für gewisse Zwecke ist es aber schon ok und es ist einfach umzusetzen.
          Ein Sperrmechanismus ist ein wahnsinns Aufwand und man muss auch bedenken dass die Sperre im Fehlerfall durch eine Automatik wieder aufgehoben werden muss.
          Wenn das bearbeitende Programm abstürzt hat man die nächsten x Minuten keinen Zugriff mehr und so weiter.

          1. Tach!

            Ein Sperrmechanismus [...] man muss auch bedenken dass die Sperre im Fehlerfall durch eine Automatik wieder aufgehoben werden muss.
            Wenn das bearbeitende Programm abstürzt hat man die nächsten x Minuten keinen Zugriff mehr und so weiter.

            Jein. Das Risiko kann man minimieren. Es ist nur dann gegeben, wenn man einen zufallsgenerierten Wert als Sperrkennzeichen verwendet und der mit einer Session verlorengeht (Browser-Absturz und Session-ID-Cookie-Verlust). Sperrt man mit der Benutzerkennung, dann ist die Chance des Nicht-Entsperren-Könnens bei praktisch Null.

            dedlfix.