Konkurierende Datenbankzugriffe verhindern

Dieses Thema im Forum "Ruby, php, Perl, Python ..." wurde erstellt von nibel, 29.08.2011.

  1. nibel

    nibel Doppel-As

    Dabei seit:
    29.12.2006
    Beiträge:
    114
    Zustimmungen:
    0
    Hallo Gemeinde,

    ich bin gerade dabei hier eine Software in PHP für telefonische Kundenbefragungen zu erweitern, der verwendete DB-Server ist Mysql:

    Konkret geht es um die Zugriffe auf die einzelnen Kundendatensätze, der vorherige Programmierer hat dabei jeweils einen Timestamp für den letzten Zugriff weggeschrieben und darauf geprüft, damit dieser nicht gleichzeitig geöffnet wird und nach dem letzen Zugriff ne gewisse Zeit vergeht, bevor er noch Mal angefasst wird.

    Nun wurden aber weitere Mitarbeiter auf die Telefonie angesetzt, nun kommt es immer häufiger vor, Mitarbeiter B auf den Datensatz zugreift, bevor Mitarbeiter A, welcher ebenfalls diesen Datensatz bearbeiten will seinen Timestamp weggeschrieben hat..

    Wie kann ich dieses Verhalten am elegantesten und bequemsten unterbinden?

    Wenn es keine Webapplikation wäre, würde ich einen Dienst laufen lassen, welcher den einzelnen Mitarbeitern die ID's zuweist....

    Bietet die Datenbank geeignete Funktionalitäten, um dies zu verhindern?

    Kann ich irgendwie ne Queue bauen, oder sollte ich mit locks arbeiten?

    Danke und VG
     
  2. Anzeige

    Schau dir mal diesen Ratgeber an. Viele Antworten inkl. passender Shell-Befehle!
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 kartoffel200, 29.08.2011
    kartoffel200

    kartoffel200 AMD Fanboy Since 2003

    Dabei seit:
    12.03.2007
    Beiträge:
    938
    Zustimmungen:
    0
    Ort:
    L wie localhost
    Entschuldige bitte, ich hab nicht wirklich Ahnung von DBs, aber realisiert das nicht der DB Sheduler?
     
  4. nibel

    nibel Doppel-As

    Dabei seit:
    29.12.2006
    Beiträge:
    114
    Zustimmungen:
    0
    Der ist wohl eher eine "Cron-Lösung" für Stored Procedures.
     
  5. #4 bitmuncher, 29.08.2011
    bitmuncher

    bitmuncher Der Stillgelegte

    Dabei seit:
    08.05.2007
    Beiträge:
    3.167
    Zustimmungen:
    0
    Du könntest einen Spread Message Bus - http://spread.org/ - hinter die Webapp klemmen. Auf diesen könntest du eine Nachricht setzen, dass Datensatz mit der ID NN gerade in Benutzung ist und die Webapp schaut zuerst auf dem Message Bus nach ob dort die ID des Datensatzes zu finden ist. Nur wenn sie dort nicht ist, öffnet sie den Datensatz.

    Mit Locks wirst du vermutlich nicht weit kommen. Diese beziehen sich auf ganze Tabellen. Allgemein sollten sich konkurrierende Zugriffe aber durch Transaktionen verhindern lassen. Wie oft ein Datensatz offen ist, sollte ja keine grosse Rolle spielen. Man will ja lediglich beim Speichern/Schreiben die Race Conditions vermeiden.
     
  6. nibel

    nibel Doppel-As

    Dabei seit:
    29.12.2006
    Beiträge:
    114
    Zustimmungen:
    0
    Da hast du mich auf ne Idee gebracht! Spread klingt echt toll ich werde es mir mal anschauen, allerdings überlege ich, ob ich das nicht auch mit Memcached hin bekomme.
     
  7. #6 bitmuncher, 31.08.2011
    bitmuncher

    bitmuncher Der Stillgelegte

    Dabei seit:
    08.05.2007
    Beiträge:
    3.167
    Zustimmungen:
    0
    Auch mit memcached sollte das machbar sein. Allerdings solltest du irgendwie (z.B. über einen Cronjob) sicherstellen, dass beim Runterfahren des Systems die Daten aus dem Memcache mit der DB synchronisiert werden. Bei einem Stromausfall hast du allerdings schlechte Karten, wenn du keine USV einsetzt.
     
  8. #7 MC Raph, 01.09.2011
    MC Raph

    MC Raph Eroberer

    Dabei seit:
    03.12.2002
    Beiträge:
    55
    Zustimmungen:
    0
    Ort:
    Österreich
    Bin jetzt auch kein Datenbank-Experte, aber kannst du nicht in deiner Tabelle eine Spalte "Lock" (bool) hinzufügen und diese zum Sperren das Datensatzes verwenden? Ein Benutzer, der auf einen Datensatz zugreift setzt Lock=true und alle anderen können dann eben nur lesen, bis der Datensatz wieder freigegeben wurde.

    magixD

    Edit: Ist natürlich blöd wenn zwei Benutzer gleichzeitig darauf zugreifen, dann locken beide die Tabelle und beide Denken sie dürften schreiben. Etwas abgewandelte Idee:
    Du schreibst in die Lock-Spalte die BenutzerID (oder den Computer-Namen, oder sonst irgend einen eindeutige Zeichenkette). Ein Benutzer, der den Datensatz öffnet schaut nun ob Lock leer ist, wenn ja schreibt er seine ID und liest dann das Lock-Feld noch einmal aus: steht seine ID drinnen hat er gewonnen, steht eine andere drinnen gab es einen plesiosynchronen Zugriff und der andere hat gewonnen.
     
  9. amöbe

    amöbe Tripel-As

    Dabei seit:
    21.01.2007
    Beiträge:
    188
    Zustimmungen:
    0
    Man könnte es auch so machen: Wenn die Telefonisten den Eintrag öffnen wird erstmal nichts geprüft o.ä., da die Daten ja manchmal nur betrachtet werden. Jeder Eintrag hat aber eine Zeit der letzten Bearbeitung gespeichet, die auf der Webseite z.B. in einem hidden input mit gespeichert ist. Wenn jetzt das Formular gesendet wird, also gespeichert wird, wird verglichen, ob der gesendete Timestamp mit dem im Datensatz übereinstimmt. Ist er gleich, wird einfach gespeichert und ein neuer Timestamp gesetzt. Ist er anders, hat also zwischenzeitlich jmd anderes gespeichert, wird der neue Datensatz mit dem Formular angezeigt und der Benutzer kann dann entscheiden, ob er wirklich Überspeichern will oder Änderungen einpflegen.
     
Thema:

Konkurierende Datenbankzugriffe verhindern