jo: Einträge von mehreren Benutzern gleichzeitig bearbeitet werden

Hallo,

Ich bin dabei eine Administration zu schreiben, in welcher eine unbekante Anzahl an Benutztern gleichzeitig zugriff haben können um Einträge zu bearbeiten.

Das Problem was sich mir jetzt stellt ist, das wenn ein Beitrag gerade bearbeitet wird, dieser nicht noch von einem anderen Benutzter bearbeitet werden kann.

Ich habe mir das so gedacht,
1. ein benutzter klick auf den entsprechenden Eintrag auf einen button EDIT
2. indem moment wird ein feld auf 1 gesetzt (1=in arbeit , 0=kann bearbeitet werden)

Anhand diese feldes könnte ich feststellen welche Einträge gerade bearbeitet werden und felder mit dem wert 1 können nicht bearbeitet werden.

Damit ein Eintrag mit dem wert 1 wieder beatbeitbar wird (=0) muß der Beitrag abgeschlossen werden. Die action des formulars verweist auf eine Seite die das erledigt.

[Jetzt meine Frage]
Wenn ein Benutzter einen Eintrag zum bearbeiten anklickt (=1) und er sich vertan hat, und den beitrag nicht abschließ (=0), weil er einfach das Browser Fenster schließt oder weil er back klickt oder vielleicht sogar manuell etwas in der adresszeile eingibt.

in diesem fall bleib das feld auf 1 stehen könnte nich mehr bearbeitet werden.

Wie würdet ihr sowas machen ?

gruß

jo

  1. Hello Jo,

    Pessimistic Locking funktiomniert nur in einem verbindungsorientierten System. Du hast ja schon erkannt, dass sonst ggf. diverse "Lost Marks" zurückbleiben könnten.

    Du kannst im Prinzip nur optimistic Locking mit Write-Counter benutzen. Es ginge da sicher auch ein "Micro-Timestamp", der fein genug ist, dass es keine zwei gleichen geben könnte. Da bleibt dann aber immer eine kleine Unsicherheit. Schreibzähler im Datensatz ist daher besser geeignet.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

  2. Hi,

    Wenn ein Benutzter einen Eintrag zum bearbeiten anklickt (=1) und er sich vertan hat, und den beitrag nicht abschließ (=0), weil er einfach das Browser Fenster schließt oder weil er back klickt oder vielleicht sogar manuell etwas in der adresszeile eingibt.

    ... anstatt den Cancel-Button zu verwenden, den Du hierfür anbietest.

    Wie würdet ihr sowas machen ?

    Mit einem Timeout.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  3. Hi,

    ich würde hingehen und bei einem OnUnload alles auf 0 setzen :)

    Aber das speichern vorher nicht vergessen.

    1. Hi,

      ich würde hingehen und bei einem OnUnload alles auf 0 setzen :)

      einen Workaround für einen Workaround? Das klappt nicht.

      Aber das speichern vorher nicht vergessen.

      Daten zu speichern, die jemand offensichtlich nicht speichern möchte, ist in aller Regel nicht das, was man machen möchte.

      Cheatah

      --
      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
    2. hallo,

      Da ich nie sicher bin das JavaScript auf den entsprechenden Clients läuft werde ich nichts mit JS machen.

      ich würde hingehen und bei einem OnUnload alles auf 0 setzen :)

      Aber das speichern vorher nicht vergessen.

      danke

      jo

  4. Hi,

    Wenn ein Benutzter einen Eintrag zum bearbeiten anklickt (=1) und er sich vertan hat, und den beitrag nicht abschließ (=0), weil er einfach das Browser Fenster schließt oder weil er back klickt oder vielleicht sogar manuell etwas in der adresszeile eingibt.

    Man könnte die Sperre für eine bestimmte Dauer/User setzen, jeder Speichvorgang des Users verlängert diese Dauer. Läuft dieser Zeitraum aus ist die Datei freigegeben und kann ggf. von jemand anderem übernommen werden.
    Wer also zwischendurch Kaffee trinken geht hat Pech gehabt ;-)

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
    1. Hello,

      Man könnte die Sperre für eine bestimmte Dauer/User setzen, jeder Speichvorgang des Users verlängert diese Dauer. Läuft dieser Zeitraum aus ist die Datei freigegeben und kann ggf. von jemand anderem übernommen werden.

      Die wirklichen Probleme treten erst auf, wenn nicht ein Einzeldatansatz bearbeitet werden muss, sondern die konsistente Bearbeitung einer ganzen Datensatzgruppe aus einer Tabelle oder sogar aus mehreren sichergestellt werden muss.

      Wenn dann einer dazsichen ist, der eine solche "Zeitsperre" hat, steht das System zeitweise oder es gibt sogar DeadLocks, also gegenseitige Behinderungen, die das System dann ganz zum Stehen bringen können.

      Man muss also immer erst für eine überschneidungsfreie Serialisierung der Anforderungen sorgen.

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

  5. Moin!

    Wie würdet ihr sowas machen ?

    Es hängt etwas davon ab, wie genau die Daten aussehen, und was umständlicher oder einfacher zu machen ist, aber im Prinzip würde ich entweder:

    1. Eine History aller Speichervorgänge einrichten, d.h. eine Datenbanktabelle, die immer nur mit INSERT gefüllt wird, und in die sämtliche zu speichernden Daten geschrieben werden. Ein einzelner Prozess generiert dann aus diesen Daten ein neues, aktualisiertes Abbild in der eigentlichen Tabelle, und zwar so, dass die Änderungen in der Reihenfolge nacheinander eingetragen werden.

    oder

    2. Beim Speichern eines Datensatzes wird verglichen, ob dieser Datensatz seit dem Lesen (für die Bearbeitungsanzeige) verändert wurde, indem das Formular die Lesezeit in einem Hiddenfeld zurück schickt, und der Datensatz ein Timestamp-Feld enthält (das aktualisiert sich, wenn man es nicht explizit auf eine Zeit setzt, bei INSERT und UPDATE in dem Datensatz immer auf die aktuelle Zeit), mit dem man vergleichen kann. Wenn seit dem Lesen des Datensatzes in der DB Änderungen vorgenommen wurden, muß der Benutzer den veränderten neuen und seinen bearbeiteten Datensatz nochmal vorgelegt bekommen, um zu entscheiden, welche Version, ggf. auch detaillierter welche Datenfelder genau zu übernehmen sind.

    - Sven Rautenberg

    --
    My sssignature, my preciousssss!
    1. Hello,

      Wenn seit dem Lesen des Datensatzes in der DB Änderungen vorgenommen wurden, muß der Benutzer den veränderten neuen und seinen bearbeiteten Datensatz nochmal vorgelegt bekommen, um zu entscheiden, welche Version, ggf. auch detaillierter welche Datenfelder genau zu übernehmen sind.

      Ein Beispiel dafür, auf Filelockbasis und Flatfiles gibts unter http://selfhtml.bitworks.de --> Adressverwaltung

      Wenn da zwei User gelichzeitig denselebn Datensatz ändern, antwortet das System mit beiden Versionen.

      In der Praxis sollte man das allerdings auf Satzebene oder sogar auf Feldebene herunterbrechen, damit die Behinderungen klein bleiben.

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

    2. hallo,

      1. Beim Speichern eines Datensatzes wird verglichen, .....................

      die 2 Lösung hört sich interessant an, werde die 1 aber auch mal in erwägung ziehen.

      danke

      gruß

      jo

  6. hallo,

    in diesem fall bleib das feld auf 1 stehen könnte nich mehr bearbeitet werden.
    Wie würdet ihr sowas machen ?

    Ich benutze Sessions, die von der Datenbank verwaltet werden. In meiner Session-Wrapper-Klasse habe ich dafür die Session-Destroy-Funktion _destroy() mit hierfür notwendigen SQL-Statements erweitert. Jedes mal wenn ein Session vernichtet wird, werden alle Werte, die auf 0 gesetzt werden müssen tatsächlich auf 0 gesetzt. Habe bisjetzt keine Probleme beobachtet.

    Grüße aus Berlin,

    tufi

    1. Hello,

      in diesem fall bleib das feld auf 1 stehen könnte nich mehr bearbeitet werden.
      Wie würdet ihr sowas machen ?

      Ich benutze Sessions, die von der Datenbank verwaltet werden. In meiner Session-Wrapper-Klasse habe ich dafür die Session-Destroy-Funktion _destroy() mit hierfür notwendigen SQL-Statements erweitert. Jedes mal wenn ein Session vernichtet wird, werden alle Werte, die auf 0 gesetzt werden müssen tatsächlich auf 0 gesetzt. Habe bisjetzt keine Probleme beobachtet.

      Und wie machst Du das im HTTP-Umfeld?
      Da gibt es keine Verbindungskontrolle über die Session.

      Harzliche Grüße vom Berg
      http://www.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau

      1. hallo,

        Und wie machst Du das im HTTP-Umfeld?
        Da gibt es keine Verbindungskontrolle über die Session.

        aehm; ist die Frage, wie ich es ohne PHP-Session machen würde ?
        oder meinst du es gibt Umfelder, in denen PHP-Session nicht so arbeitet wie ich sie gerne hätte ?

        Grüße aus Berlin,

        tufi

        1. Hello,

          Und wie machst Du das im HTTP-Umfeld?
          Da gibt es keine Verbindungskontrolle über die Session.

          aehm; ist die Frage, wie ich es ohne PHP-Session machen würde ?
          oder meinst du es gibt Umfelder, in denen PHP-Session nicht so arbeitet wie ich sie gerne hätte ?

          Die Frage war, wie Du vergessene Sperren rechtzeitig wieder entfernst.
          Einen Datensatz für die Dauer der Session + einer Restlebensdauer gesperrt zu halten, ist nicht die feine Art. Sowas sollte innerhalb von Sekunden oder noch besser Sekundenbruchteilen erledigt sein.

          Harzliche Grüße vom Berg
          http://www.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau

          1. hallo,

            Die Frage war, wie Du vergessene Sperren rechtzeitig wieder entfernst.
            Einen Datensatz für die Dauer der Session + einer Restlebensdauer gesperrt zu halten, ist nicht die feine Art. Sowas sollte innerhalb von Sekunden oder noch besser Sekundenbruchteilen erledigt sein.

            das stimmt allerdings.. Die von mir vorgeschlagene Methode funktioniert ohne Restzeit meines Wissens nicht..

            Grüße aus Berlin,

            tufi