# Gleichzeitiger Zugriff auf Datensatz



## Camino (7. Nov 2010)

Hallo,

ich entwickle zur Zeit eine Swing-Anwendung (Verwaltungstool), welche auf eine PostgreSQL-Datenbank zugreift, d.h. genauer, es soll mehrere Clients geben, die über JDBC auf eine PostgreSQL-DB auf einem externen Server (über TCP/IP) zugreifen. Praktisch ist es ziemlich unwahrscheinlich (ca. 5 Anwender gleichzeitig, die räumlich zusammenhängen), aber theoretisch möglich, dass gleichzeitig zwei oder mehrere Anwender auf den selben Datensatz in der Datenbank zugreifen und ändern könnten. Gibt es eine Möglichkeit, wie es dies ausschliessen und verhindern kann?

Ich dachte evtl. an ein Feld in der Datenbank-Tabelle, welches speichert, ob und welcher Anwender gerade an dem Datensatz arbeitet und dies dann für andere Anwender sperrt. Oder gibt es eine andere und bessere Möglichkeit?

Gruss
Camino


----------



## Marcinek (7. Nov 2010)

Klassisches Problem

Siehe

Optimistic Locking

Pesimistic Locking


----------



## Camino (7. Nov 2010)

Hallo,

und danke. Das kannte ich noch nicht...

Brauche ich dafür Hibernate o.ä., oder kann ich das in meine Swing/JDBC-Anwendung einbauen? Wenn ich das richtig verstanden habe, hole ich mir bei Optimistic Locking vorher den Datensatz, und überprüfe beim Speichern, ob dieser geholte Datensatz immer noch aktuell in der DB ist, erst dann wird er in die DB geschrieben und aktualisiert. Das Problem dabei scheint zu sein, dass wenn dann ein Problem auftritt (Datensatz wurde zwischenzeitlich geändert), dass es dann evtl. komplizierter werden kann, weil überlegt werden mus, was zu tun ist.

Pessimistic Locking schliesst von vorne gleich aus, dass ein anderer den Datensatz holen, bearbeiten und wieder in der DB speichern kann. Scheint mir eigentlich vorteilhafter. Hab aber noch nicht gefunden, wie das umgesetzt wird. Werde mal weiter suchen...

Gruss
Camino


----------



## Marcinek (7. Nov 2010)

nein du brauchst natürlich nicht hibernate dafür.

Optimistic Locking: Es wird eine Version pro Datensatz gespeichert. Jedes Schreiben inkrementiert die Version.

Ablauf

User 1 holt datensatz mit version 1
User 2 holt datensatz mit version 1
User 1 speicher datensatz version 1= > version 2
User 2 möchte speuchern ==> Seine Version ist 1 aktuelle ist 2 ==> Fehler: Der Datensatz wurde zwischenzeitlich geändert:

 - Hier kann man dennoch überschreiben
 - Zum reloaden (Änderungen verwerfen und nochmal machen) zwingen

Pesimistic Locking ist aufwendiger meiner Meinung nach.

Du speichertst in der DB an. welcher Datensatz sich in welchem Zustand befindet.

User 1 öffnet Datensatz zum bearbeiten ==> Lock wird in DB geschrieben.
User 2 öffnet Datensatz zum bearbeiten ==> Fehler: Anderer User schreibt Datensatz wird zum anzeigen geladen.

Ähnlich wie bei Word, wenn man 2x auf die gleiche Datei zugreift

Gruß,
Martin


----------



## Gast2 (7. Nov 2010)

PostgreSQL: Documentation: Manuals: PostgreSQL 8.1: SELECT

Schau mal unter dem Abschnitt "FOR UPDATE/FOR SHARE Clause"


----------



## Camino (8. Nov 2010)

Hallo,

für "FOR UPDATE/FOR SHARE Clause" braucht man Transaktionen. Hab mich damit leider noch nicht beschäftigt, werde ich mir aber mal anschauen.

Meine Ausgangslage ist so, dass ich mir die (gefilterten) Datensätze aus der PostgreSQL-DB in eine ArrayList<Person-Objekt> hole, und dann innerhalb dieser Liste blättern kann, wobei immer der aktuelle Datensatz dann in einem Formular angezeigt, verändert und wieder gespeichert werden kann. Das bedeutet, die anderen Clients bekommen garnicht mit, wenn ein Client einen Datensatz bearbeitet. Da würde dann ja das Optimistic Locking funktionieren, d.h. ich überprüfe beim Speichern der Änderung, ob der vorher geholte Datensatz mit der aktuellen Versionin der DB noch übereinstimmt (Vergleich von Personen-Objekten). Erst dann kann das Update erfolgen. Wenn nicht, kommt eine Mitteilung, dass sich der Datensatz in der Zwischenzeit geändert hat und neugeladen und aktualisert angezeigt wird. Dabei gehen dann aber die zuvor gemachten Änderungen im Formular verloren und müssen neu eingegeben werden.

Innerhalb dieses Formulars (Personen-Eingabemaske) gibt es noch eine Antragsübersicht in einer JTable. Durch Doppelklick einen Eintrag wird ein bestimmter Antrag ausgewählt und dann in einem anderen Formular (Antrag-Eingabemaske) angezeigt. Dort kann dann geändert und gespeichert werden. Dafür wäre ja nun das Pessimistic Locking geeignet, da ich ja durch Doppelklicken in der Tabelle Antragsübersicht deutlich mache, dass ich einen Antrag zum evtl. Ändern angezeigt bekommen möchte, und in dieser Zeit niemand anderes an diesen Antragsdaten arbeiten kann/darf. Dazu müsste ich dann in der DB-Tabelle 'Anträge' ein Feld haben, welches speichert, wer gerade an diesem Datensatz arbeitet, und dies beim Verlassen des Datensatzes wieder entfernen. Wäre das so richtig? Was passiert, wenn aus irgendwelchen Gründen das Locking nicht entfernt wird? Zum Beispiel  Stromausfall, Computerabsturz....?

Gruss
Camino


----------

