Sperrung von einzelnen Datensätzen

warcraft9105

Erfahrenes Mitglied
Hallo,

ich bin gerade dabei eine Anwendung zu schreiben, die von mehreren Personen gleichzeit ausgeführt werden kann. Die Anwendung beinhaltet eine Datenbank. Damit ein Datensatz nicht mehrere male gleichzeitig bearbeitet werden kann, brauche ich ein Sperrkonzept.
Nun habe ich mir folgendes überlegt:
Wenn eine Person einen Datensatz bearbeiten will, erzeuge ich ein Objekt von diesem Datensatz und verknüpfe ihn mit dieser Person. Sobald die Bearbeitung abgeschlossen ist, wird dieses Objekt gelöscht. D. h. wenn eine zweite Person in die Bearbeitung gehen und den Datensatz bearbeiten möchte, wird geprüft ob ein Objekt von diesem Datensatz mit einer anderen Person existiert. Wenn nicht, darf der Datensatz bearbeitet werden.

So weit so gut. Mein Problem ist nur, dass ich nicht weiß, wie bzw. wo ich diese Objekte speichern soll, damit alle Instanzen meiner Anwendung darauf zugreifen können.

Hat da jemand einen Rat bzw. eine Idee?

Gruß,
warcraft9105
 

RudolfG

Erfahrenes Mitglied
Hi,

ich würde, die Information das der Datensatz bereits gesperrt ist, in einer eigenen Tabelle abspeichern.

Aufbau ungefähr:

SQL:
create table gesperrte_datensaetze 
{
   ID integer primary key, -- autoincrement wenn vorhanden
   Type integer, -- Hier kannst du in der Anwendung in einem enum festlegen, dass z. B. du Objekte von z. B. dem Typ Mitarbeiter, Bestellung, Rechnung etc. und den Wert hinter dem Enum speicherst du hier ab.
   Datensatz_id integer,
   Benutzer_id integer, -- foreign key 'cascade' auf die Login-Tabelle, damit wird der Datensatz automatisch freigegeben sobald sich der Benutzer ausloggt und der login-Datensatz aus der Tabelle gelöscht wird.
);

Möchte jetzt ein Anwender einen bestimmten Datensatz von z. B. einem Mitarbeiter bearbeiten überprüfst du in der Anwendung ob die id des Datensatzes mit dem Typen für Mitarbeiter sich in der Tabelle gesperrte_datensaetze befinden, sollte es der fall sein, so ist dieser Datensatz von jemand anderen zum bearbeiten geöffnet, anderseits kann man den Datensatz öffnen.

Natürlich musst du beim Beenden des Bearbeitungsvorgangs diesen Datensatz auch aus der gesperrte_datensaetze-Tabelle entfernen. Solltest du es mal vergessen haben, wird der Datensatz beim Logout des Benutzer automatisch freigeben.
 

warcraft9105

Erfahrenes Mitglied
Hallo,

danke für deine Antwort. An eine extra Tabelle hab ich schon gedacht, das Problem ist nur, dass nicht jede Tabelle einen Schlüssel hat, der nur über eine Spalte geht. Dadurch funktioniert das mit der Tabelle nicht.
Was mich jedoch interessiert ist, wie das mit dem automatischen Freigeben des Datensatzes beim Logout funktionieren soll. Was ist wenn die Anwendung abstürzt? Oder gar der ganze PC?

Gruß,
warcraft9105
 

RudolfG

Erfahrenes Mitglied
Hallo,

danke für deine Antwort. An eine extra Tabelle hab ich schon gedacht, das Problem ist nur, dass nicht jede Tabelle einen Schlüssel hat, der nur über eine Spalte geht.
Dadurch funktioniert das mit der Tabelle nicht.

Es muss ja nicht der Schlüssel einer Tabelle sein, es muss ja bestimmte Merkmale geben anhand dennen du die jeweiligen Objecte unterscheiden kannst, oder?

z. B.

- Jeder Mitarbeiter hat eine Mitarbeiter-Nummer die einmalig ist
- Jedes Projekt hat eine Projektnummer
- Jede Rechnungsnummer hat eine Rechnungsnummer
- Jede Bestellung eine Bestell-Nr
etc.

Oder worum genau geht es den bei deinen Objekten?

\edit: Als (Zeitintensivere) Alternative könntest du die mehreren Schlüssel aneinanderhängen (oder sonst irgendwie zusammenfügen) und Hashen, das Ergebnis wird dann als Schlüssel eingetragen. Da du noch zusätzlich angibst um welche Art Objekt es sich handelt, müssten das einmalige Schlüssel sein.


Was mich jedoch interessiert ist, wie das mit dem automatischen Freigeben des Datensatzes beim Logout funktionieren soll. Was ist wenn die Anwendung abstürzt? Oder gar der ganze PC?

Ja gut, dann funktioniert es natürlich nicht automatisch. Beim erneuten Login wird einem mitgeteilt, dass noch eine Session des Benutzers in der DB vorhanden ist und ob man diese Löschen möchte. Löscht man diese werden über die Referenz zu der Lock-Tabelle auch die gelockte Objekte wieder freigegeben.

Aber vielleicht bietet der von dir benutze SQL-Server Möglichkeiten beim Verlust von Verbindungen bestimmte Operationen zu hinterlegen, dann währe es möglich diese Aufräum-Arbeiten durchführen zu lassen.

Gruß
RudolfG
 
Zuletzt bearbeitet:

warcraft9105

Erfahrenes Mitglied
Hallo RudolfG,

nur so als kleine Nebeninformationen. Meine Anwendung ist eine Desktop-Anwendung und als DB habe ich mich für Access entschieden.

Ich glaube das mit dem "zusammenfügen" der Schlüssel in einer Spalte werde ich so machen.

Das Problem, dass der Datensatz evtl. nicht gelöscht wird, da Programmabsturz o. Ä., werde ich so lösen, dass ich zu der Lock-Tabelle noch eine Datumsspalte anhänge. Damit kann ich prüfen, ob die Sperrung länger als eine bestimmte von mir definierte Zeit her ist (z. B. 15 min). In der Anwendung lasse ich dann einen Timer laufen (Intervall von z. B. 5 min), der dieses Datumsfeld aktualisiert.

Ist das Programm nun abgestürzt ist der Datensatz für maximal 15 min (im Beispiel) gesperrt. Und damit die Datenbank/Tabelle nicht zugemüllt wird, wird bei jedem Programmstart die Tabelle bereinigt, sodass alle Eintrage, die älter als 15 min (im Beispiel) sind, gelöscht werden.

Hoffe, ich konnte es einigermaßen erklären was ich meine.
Für Kritiken/Verbesserungsvorschläge bin ich sehr offen ;)

Gruß,
warcraft9105
 

RudolfG

Erfahrenes Mitglied
Also ich würde es so machen!

Du musst nur beachten, dass es je nachdem um welche Objekte es sich handelt ggf. zu Datenverlust kommen kann.

Bei uns z. B. werden Texte (also eine Art von Word-Dokumente) in der DB gepflegt und ich als Entwickler kann hier einfach nicht nach einer bestimmten Zeit den Datensatz für andere Freigeben und somit die Arbeit eines anderen vernichten. Stell dir mal vor, du arbeitest den ganzen Tag an einem Text (formulierst ihn aus aber musst zwischendurch auch Telefonieren etc.) da du vergessen hast regelmäßig zu speichern (damit den Lock-Eintrag zu aktualisieren) ist plötzlich alles weg...

Gruß
RudolfG

PS: Sollten damit alle deine Fragen beantwortet sein und der Thread somit für dich erledigt, markier den Thread auch bitte als markiert.
 

warcraft9105

Erfahrenes Mitglied
Zu deinem gennanten Problem:
Der Lock-Eintrag wird nicht nur aktualisiert, wenn der Benutzer speichert, sonder im Hintergrund läuft ein Timer, der alle paar Minuten den Eintrag aktualisiert. Somit dürfte das Problem nicht auftreten.
Oder verstehe ich deine Problemstellung falsch?

Gruß,
warcraft9105