# Datensatz exklusiv öffnen



## MScalli (12. Nov 2009)

Hi leutz.
Ich hab jetzt meine Frage schon anderen Foren gestellt und habe leider keine Antwort erhalten, obwohl ich glaube das genau diese Anforderung eigentlich sehr oft gebraucht wird.

Ich habe es schon in verschiedenen Richtungen probiert, aber ich fang hier einfach mal ganz von vorn an.

Ich habe Daten in einer PosgreSQL-Datenbank und will z.B. einen Artikel 'Exklusiv' öffnen'.
D.h. wenn ein User einen Artikel zum bearbeiten geöffnet hat soll dies kein anderer User machen können.
Ich könnte dies über einen SQL-Befehl zwar locker sperren(connection öffnen, SQL-Befehl 'SELECT .... FOR UPDATE' dann ist dieser Satz bis zum commit der Connection gesperrt) aber wenn zu dieser Zeit ein zweiter user den Datensatz bearbeiten will merkt er nicht das dieser gesperrt ist. Denn java wartet einfach bis der erste User fertig ist und führt danach den befehl des anderen Users aus.. egal wie lange das auch dauert!!

Wie kann ich dieses Problem lösen???
Also User 1 öffnet einen Datensatz 'exklusiv'. Wenn User 2 jetzt diesen Satz öffnen möchte soll er eine Meldung bekommen 'Datensatz wird gerade bearbeitet'

Bitte schaut es euch mal an denn ich verzweifle langsam


----------



## Hrtgpdh (12. Nov 2009)

Habe ich vor einiger Zeit mal gefunden:

Exklusiver Zugriff auf Datensatz in einer PortgreSQL-Datenbank - Java @ tutorials.de: Forum, Tutorial, Anleitung, Schulung & Hilfe

Ansonsten wenn die PostgreSQL- DB keinen exklusiven Zugriff möglich macht, kannst du immer noch in einer eigenen Tabelle protokollieren, welche Datensätze geöffnet sind, nicht schön aber bei manchen Datenbanken geht es manchmal nicht anders.


----------



## Gast2 (12. Nov 2009)

Moin,

mach Dich mal bitte mit dem Transaktions-Konzept von Datenbank vertraut ... die meisten Frameworks bieten dazu einiges an ... außer dem lief das (ähnliche) Thema diese Woche schon - such mal im Forum

hand, mogel


----------



## MScalli (12. Nov 2009)

@ mogel - Ich hab mir diesen Thread mehrfach durchgelesen und auch mal das Thema Hibernate angeschaut.. aber ehrlich gesagt ist das ein Thema das ich nicht so hoppla hopp in Griff bekomme.
-> Ich werde mich aber auf jeden Fall damit beschäftigen denn das sieht echt gar net so blöd aus 

@ Hrtgpdh - GENAU DAS IST ES.
Wenn ein 2ter User auch einen SELECT .. FOR UPDATE NOWAIT absetzt bekommt er(endlich) eine Exception.
Ich habe mich glaub noch nie über eine Exception so gefreut wie heute^^

Ich hoffe nur ich habs richtig verstanden, denn ich habe mir mit 

```
System.out.println(ex.getErrorCode());
```
den ErrorCode geholt(war 0) und kann jetzt eigentlich in der Exception abfragen

```
if(x.getErrorCode()==0){
   System.out.println("Satz ist gesperrt");
}
```

Ich hoffe nur 0 ist der richtige ErrorCode da er eigentlich nur aussagt das dieser Satz nicht gesperrt werden kann..
was in meinem Fall ja aussagt das er schon gesperrt ist.
Oder?!?!


----------



## tfa (12. Nov 2009)

Das musst du wohl in der Dokumentation nachschlagen.
Trotzdem bindest du dich mit dieser Technik an ein bestimmtes DB-Produkt, d.h. ein Wechsel
könnte unnötig kompliziert werden.
Ich würde so eine Funktion im Application-Server programmieren, und nicht mit DB-Locking.


----------



## RaoulDuke (17. Nov 2009)

tfa hat da völlig recht, das eine Sache die nicht in die Datenbank gehört. Das ist Applikationslogik was du hier willst. Mach dir eine Map (auf Threadsicherheit achten), in der du die IDs der gerade zum Bearbeiten geöffneten Artikel speicherst. Will ein User einen Artikel editieren, dann prüfst du ob die ID in der Map ist. Wenn ja, dann gib die Fehlermeldung das der Artikel in Bearbeitung ist, wenn nein dann pack die ID des Artikels den der User bearbeiten will da rein und lass ihn den Artikel bearbeiten. Ist der User mit Bearbeiten fertig, speicher den Artikel und nimm du die ID wieder aus der Map raus.

Das hat den Vorteil, dass man unabhängig von der verwendeten Datenbank und auch generell der Speichertechnik ist. Das kann man z.B. auch gut mit Dummy DAOs testen, ganz ohne eine Datenbank. 

Die Lockingmechanismen der Datenbank sollten nur der letzte Rettungsanker für die Datenkonsistenz sein. Man sollte auch niemals Datenbank-Locks benutzen, die sich über längere Zeit hinziehen, sonst hat man schnell ganz doofe Probleme.


----------

