AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Simultaner Zugriff auf Datenbank (Multiuser)
Thema durchsuchen
Ansicht
Themen-Optionen

Simultaner Zugriff auf Datenbank (Multiuser)

Ein Thema von s.h.a.r.k · begonnen am 23. Nov 2006 · letzter Beitrag vom 24. Nov 2006
Antwort Antwort
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 09:28
Datenbank: MySQL • Version: 5.x • Zugriff über: libsql/ZeosLib (bisher noch nicht fest)
Guten Morgen,

ich mache mir gerade Gedanken bzgl. einem Projekt, das ich in der Zukunft umsetzen soll. Und zwar handelt es sich dabei um ein Projekt, das Multiuserfähig sein soll, d.h. dass mehrere Benutzer auf die gleichen Daten in einer Datenbank zugreifen sollen. So weit so gut, denn MySQL kann das ja. Nun habe ich aber das Problem (bzw. die ein paar schlechte Erfahrungen mit Threads gemacht), dass so ein simultaner Zugriff auf Daten nicht immer glatt über die Bühne geht. Nach meinem Wissensstand lässt MySQL nicht zu, dass man gleichzeitig lesend auf Daten zugreifen kann. ABER bevor ich da nun zu programmieren anfange und mitten drin merke, dass meine Idee nicht zu realisieren ist frage ich doch lieber nach.

Habt ihr mir daher Vorschläge/Ideen/Anmerkungen zum folgenden Szenario, d.h. ist die folgende Lösung dazu sinnvoll und funktioniert diese, sodass ein multiuserfähiges System dabei herauskommt:

Ich gehe im nachfolgenden von einer perfekten Übertragunsgeschwindigkeit, von zwei User auf separaten Rechnern, die gleich sind und einem Server auf dem MySQL läuft aus. Die beiden User haben in der Datenbank die vollen Lese- und Schreibrechte.

Zwei User laden die Daten (Annahme: Kundendaten) aus der MySQL-Datenbank und lassen diese sich aufbereitet in einer Liste anzeigen. Nun wählen beide die ersten 5 Kunden aus - zur Bearbeitung. Nachdem beide auf Laden geklickt haben wird von beiden Rechnern aus der Befehl an MySQL geschickt, dass dieser Datensatz von dem jeweiligen Benutzer geladen wird, d.h. bei allen 5 Datensätzen wird eine bestimmte Zelle auf TRUE statt auf FALSE gesetzt, sodass kein anderer User darauf zugreifen kann (ich hoffe jeder versteht an dieser Stelle was ich meine). Meine Annahme ist bisher, dass MySQL nun z.B. die Anfrage (aus welchen Kriterien auch immer) des ersten Users als erstes abhandelt und die Daten für andere User sperrt. Allerdings hat dieser User auch schon auf "Laden" geklickt und die Anfrage, d.h. die Sperrung der Daten, gesendet. Wie kann ich das sinnvoll handeln, sodass es hier zu keinerlei Überschneidungen kommt?!

Über eine Antwort wäre ich ziemlich erfreut!

Mit freundlichen Grüßen
shark
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 09:35
Hi,
wenn du Anfragen serialisieren möchtest, musst du sie einfach als Transaktion (soweit von MySQL unterstützt) kennzeichnen. Eine Transaktion hat dann die Eigenschaft, dass sie atomar ist, also ganz (oder gar nicht) abgearbeitet wird. Egal wer nun zuerst die Daten prüft und dann sein Flag setzt, geschieht dies alles in einer Transaktion entspricht dies einem einzigen Schritt und das DBMS hat sich drum zu kümmern.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#3

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 10:08
Das was Du willst ist ein Lock - bzw. eine Datensatzsperre. Soweit ich weiss, kann MySQL nur ganze Tabellen sperren.

Das was Du vor hast widerspricht aber ehrlich gesagt dem Datenbankkonzept.
Prinzipiell ist es so, dass eigentlich alle immer bearbeiten dürfen (so sie denn dürfen) und beim Schreiben der Daten in die Datenbank der Client zu prüfen hat, ob die Daten vllt. vorher geändert wurden und hier dann einen Konflikt anzeigt.

Weil: Was, wenn ein Client die Tabelle lockt und dann abschmiert? Dann kann kein einziger User mehr Daten verändern, bis ein Admin die Sperre aufgehoben hat.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#4

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 12:25
Zitat von Phoenix:
Das was Du willst ist ein Lock - bzw. eine Datensatzsperre. Soweit ich weiss, kann MySQL nur ganze Tabellen sperren.

Das was Du vor hast widerspricht aber ehrlich gesagt dem Datenbankkonzept.
Prinzipiell ist es so, dass eigentlich alle immer bearbeiten dürfen (so sie denn dürfen) und beim Schreiben der Daten in die Datenbank der Client zu prüfen hat, ob die Daten vllt. vorher geändert wurden und hier dann einen Konflikt anzeigt.

Weil: Was, wenn ein Client die Tabelle lockt und dann abschmiert? Dann kann kein einziger User mehr Daten verändern, bis ein Admin die Sperre aufgehoben hat.
Gut, das ist nicht schlecht zu wissen, da ich bisher nicht all zu viel über Datenbanken und die dahinter steckenden Prinzipien weiß. Ich nutze sie halt!

Jetzt stellt sich mir halt die Frage, wie du das sinnvoll umsetzen würdest?!

Denn es macht meines Erachtens nach keinen Sinn, jeden Benutzer gleichzeitig auf die Daten zugreifen, diese ändern und dann, wenn er es speichern will, ihm eine Nachricht zukommen zu lassen, dass leider schon ein anderer Benutzer die Daten geändert hat. Das finde ich nicht sehr sinnig... Ich weiß nur nicht, wie ich das sonst machen will?!

Bzgl dem sperren einzelner Datensätze: den Absturz eines Clients (sei es ein Systemabsturz oder einfache Trennung vom Netz) habe ich durchaus berücksichtigt und hatte vor, jede Nacht um 12 Uhr (da arbeitet mit Sicherheit keiner mehr an den Daten) aller Verbindungen zu trennen und alle Daten wieder freizugeben.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#5

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 13:58
Zitat von s.h.a.r.k:
Gut, das ist nicht schlecht zu wissen, da ich bisher nicht all zu viel über Datenbanken und die dahinter steckenden Prinzipien weiß. Ich nutze sie halt!

Jetzt stellt sich mir halt die Frage, wie du das sinnvoll umsetzen würdest?!

Denn es macht meines Erachtens nach keinen Sinn, jeden Benutzer gleichzeitig auf die Daten zugreifen, diese ändern und dann, wenn er es speichern will, ihm eine Nachricht zukommen zu lassen, dass leider schon ein anderer Benutzer die Daten geändert hat. Das finde ich nicht sehr sinnig... Ich weiß nur nicht, wie ich das sonst machen will?
Was heisst leider schon? Das passiert halt ab und zu mal. Ich meine - Du musst ihn ja nicht warnen. Es geht auch anders: Der, der zuletzt die Daten ändern überschreibt die Änderung des zuvorgehenden. Der letzte gewinnt sozusagen. Das ist das gleiche Prinzip, wie Du es auch hast, wenn mehrere Leute an einer Datei im Netz arbeiten. Nur guckt dann halt der Erste in die Röhre, dessen Änderungen überschrieben werden.

Diese Information: "Die Daten wurden schon verändert (Anzeige der neuen Daten): Wollen Sie ihre Änderung wirklich speichern oder nochmal bearbeiten?" ist a) Benutzerfreundlich und b) einfach the right way to do it.

Genau das erwartet der Benutzer auch von einer Anwendung.

Auf der anderen Seite musst Du Dir die Frage gefallen lassen, wie oft dieser Fall wirklich vorkommen wird. In einer Buchhaltungssoftware mit 50+ Benutzern hatten wir solche Fälle mal zu statistischen Zwecken mitprotokolliert. Zu solchen Kollisionen kam es maximal 3 mal pro Woche. Wie gesagt: 50 Benutzer, die alle gleichzeitig auf der Datenbank waren.

Zitat von s.h.a.r.k:
Bzgl dem sperren einzelner Datensätze: den Absturz eines Clients (sei es ein Systemabsturz oder einfache Trennung vom Netz) habe ich durchaus berücksichtigt und hatte vor, jede Nacht um 12 Uhr (da arbeitet mit Sicherheit keiner mehr an den Daten) aller Verbindungen zu trennen und alle Daten wieder freizugeben.
Wir reden hier von ganzen Table-Locks. Gleich dem ersten Benutzer passiert das um halb neun Uhr morgens. Das heisst der Rest der Belegschaft darf dann heimgehen und morgen wiederkommen. Gut, die Datenbank wird den Lock irgendwann austimen lassen, das heisst je nach Konfiguration dürfen die Kollegen schon nach einer halben Stunde weiterarbeiten und den Datensatz selber sperren.

Aber was, wenn User A einen Datensatz öffnet, diesen damit sperrt, und dann einen dringenden Anruf bekommt. Noch schnell was erledigen muss, dabei aufgehalten wird.. und Du hast auf einmal über 3 Stunden einen Table-Lock auf (weil der noch seinen Rechner sperrt und die Applikation schön im Hintergrund seine Tabelle gesperrt hält) und derweil kann kein anderer User auf dieser Tabelle arbeiten...

Vergiss das manuelle Locking. Es ist zwar möglich, aber nur in extrem wenigen Ausnahmefällen wirklich Sinnvoll.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#6

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 23. Nov 2006, 16:57
Hallo,

stell dir vor,
das Bearbeiten der Daten dauert 30min.
Danach klickt er auf Speichern,
jetzt kommt die Meldung, wurden schon geändert usw...

Sinnvoll wäre es, dass er bevor er anfängt zu ändern,
eine Info bekommt, dass gerade jemand anderes dran ist.

Dass das nicht mehr so einfach wie bei Desktop-DBs ist, ist klar.

Ich würde hier mit einer Sperrtabelle arbeiten (jaja, schimpft nur rum ),
dort steht die TabellenId (Kunde=1, Auftrag=2 usw),
und der Primärschlüssel, unique index auf beide verhindert doppeltes Eintragen.
Zusätzlich 2 timestamp, und die UserId.

Ein Tiemstamp ist das Erzeugungsdatum/zeit des Eintrages,
der andere Timestamp wird über einen Timer vom gerade Bearbeitenden ständig aktualisiert,
so findet man Datenleichen, falls das Programm abstürzt.

Die Meldung "Kunde Meier wird seit 10:30 durch Herrn Müller bearbeitet"
klingt doch nicht schlecht ?


Heiko
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#7

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 24. Nov 2006, 11:09
Ich finde eure Antworten wirklich nicht schlecht und haben mir auch schon einiges weitergeholfen, aber ich habe da doch noch einige offene Punkte:

1. Ich will keine komplette Tabelle sperren - das habe ich nicht vor! (wenn dann nur einzelne Datensätze...)
2. Angenommen ich mache keine Datensatz-Sperre (d.h. keine Tabellen-Sperre) und zwei Benutzer öffnen die selben Datensätze und editieren jeweils Ihren Teil (was durchaus mehrere Minuten in Anspruch nehmen kann), dann ist die Arbeit von Person 2 komplett sinnlos investiert, wenn Person 1 etwas schneller war. Und das will ich eben nicht haben!

Bzgl. der Idee zur Datensatzsperre: Ich habe vor, dass ein Anwender mit einer Anwendung max. 5 Datensätze laden kann, d.h. max 5 Datensätze von einerm User gesperrt sind. Aus diesen Grund können nicht alle Datensätze gleichzeitig gesperrt werden. Außerdem besteht durch ein Passwort im Client die Möglichkeit alle Sperrungen aufzuheben, die von einem bestimmten Benutzer gemacht worden sind.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 24. Nov 2006, 11:21
Ich würde eine Spalte machen welche die Zeit enhält zu der mit dem ändern begonnen wurde. Ist die Zeit größer 2 Stunden gilt es als nicht mehr in Bearbeitung. Zudem kann man auch machen das beim Login eines Nutzers alle vorherigen Sperren des Nutzers aufgehoben werden (genau wie bei einem regulären Logout).
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
webcss

Registriert seit: 10. Feb 2006
255 Beiträge
 
Delphi XE2 Professional
 
#9

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 24. Nov 2006, 13:11
also ich hab das so gelöst:

User 1 ruft daten zur bearbeitung ab. Ein Timer auf dem Client wird gestartet. mit jeder eingabe (oder Mausbewegung) wird der Timer neu gestartet. Möglichkeit A: der user beendet sein Edit. B: der User macht nix und der Timer beendet das Edit.

Alles zusammen läuft jeweils in einer Transaktion. Das alles mit Firebird. Falls also wirklich mal zwei User gleichzeitig auf ein und dieselben Daten zugreifen sollten (was eher unwahrscheinlich ist) hat Firebird die Kontrolle (mittels Transaktionen) und einer schaut eventuell in die Röhre und muss warten.

Mein Tip: wenn unterschiedliche User jeweils nur einen bestimmten Bereich bearbeiten können (z.B. user 1 Adressen, User 2 Bankverbindung) solltest du dies in zwei oder mehr Tabellen packen, dann gibt's keine Probleme. Alles andere gehört dann eher in den Bereich Betriebsorganisation, denn wo ist der sinn wenn zwei user die Anschrift ein und desselben Kunden ändern, das macht keinen sinn.
"Wer seinem Computer Mist erzählt, muss immer damit rechnen..." (unbekannt)
"Der Computer rechnet damit, dass der Mensch denkt..." (auch unbekannt)
mein blog
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#10

Re: Simultaner Zugriff auf Datenbank (Multiuser)

  Alt 24. Nov 2006, 14:35
Zitat von s.h.a.r.k:
1. Ich will keine komplette Tabelle sperren - das habe ich nicht vor! (wenn dann nur einzelne Datensätze...)
Allein nur hierzu:
MySQL kann in der aktuellen Version auf MyISAM Tabellen nunmal keine einzelnen Datensätze sperren, sondern nur ganze Tabellen. Dir bleibt also hier gar nichts anderes über als ein Table-Lock.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz