Alex_winf01 hat gesagt.:
Kein Anzeigen finde ich etwas krass.. Aber es ist durchaus ein möglicher Ansatz, wenn auch nicht der empfohlene (man sollte keine Locks lange aufrecht erhalten, siehe auch ms). Aber in dem Fall ist die Alternative - eine logische Sperre (durch Datenfelder) auch nicht besonders schön.
Wir verwenden eigentlich bei uns entweder das optimistiche Locken oder die logische Sperre über eigene Felder. In deinem Fall heißt die Entscheidung pessim.Locken vs. logischer Sperre mit eigenen Feldern
Ich fasse mal kurz Vor- und Nachteile zusammen:
Sperre über Datenbank:
+ keine eigenen Felder notwendig
+ abgeschmierter Client wird irgendwann von der DB zurückgezogen
- kann sich negativ auf die Performance auswirken (Datenbank muss Sperren verwalten)
- auch SELECT muss mit Sperre arbeiten (damit man zur LockException gelangt) - Timeout setzen!
- langes Timeout --> lange Wartezeite für User, kurzes Timeout: unnötige Fehler bei z.B. Serverüberlastung
- kein teilweises Sperren/Updaten des Datensatzes möglich (eher Problem bei vorhandenen Datenbanken)
- Sperren meistens nicht vom Anwender entsperrbar
logische Sperre:
- eigene Felder notwendig
+ ein paar Felder mehr und man sieht wer den Datensatz sperrt
- wenn ein Client abschmiert, bleibt das Sperrflag stehen...
+ beim Lesen muss nicht gesperrt werden und auch keine Timeouts abgewartet werden
+ Benutzer können Sperren mit Programmhilfe ev. selber auflösen
+ Teilupdates möglich
nicht aufgeführt: optimistische Sperre (wäre wohl Sieger nach Punkten)
Zu den Feldern:
Wir verwenden für die logische Sperren meistens ein Statusfeld, welche nicht nur auf Bearbeitung stehen kann, sondern auch für storniert, fertig, unterbrochen usw. Zusammen mit anderen Feldern (letzter Sachbearbeiter, Timestamp letzte Bearbeitung) kann man bei einer Sperre auch sagen, wer den Datensatz sperrt. In Webanwendungen bzw. neuen Dateien, schreibe ich mir auch gerne die id zur Session als Sperrschalter. Wenn die Session ausläuft, entferne ich die logischen Sperren. Eine (selbst verwaltet) Sessiondatei hat bei Client/Server-Anwendungen seinen Reiz.
verlorene Sperrflags / Sperren
In beiden Fällen ist es wichtig bei allen Abbrüchen, Zurückbuttons usw. die Sperre wieder rückgängig zu machen. Bei der Datenbanksperre ist es etwas einfacher (ROLLBACK), bei der logischen Sperre den alten Status wiederherstellen. In beiden Fällen sind Programmfehler/abstürze (Exceptions!) ein Problem. Bei einem Programmfehler (Statement bleibt offen) kann auch die Datenbank nicht erkennen, dass die Sperre nicht mehr aktiv sein soll.
Auch wenn die Datenbanksperre weniger Arbeit und nach weniger Problemen aussieht, wäre das bei uns kein Option. Wenn man nicht weiß wer den Datensatz sperrt, muss man die Arbeitsplätze "durchgehen".
Ich persönlich würde mir eine Sessiondatei anlegen. Bei jeder Anmeldung wird eine Sessioneintrag für den Benutzer/IP-Adresse angelegen. Zu sperrende Sätze mit der SessionId (als Sperrschalter) versehen und zum Entsperren wieder gelöscht. Beim Abmelden die (übergebliebene) Sperren der Session entfernen und den Sessionsatz löschen bzw. auf inaktiv setzen.
Wenn es beim Anmelden mit der Kombination User/Ip-Adresse bereits eine aktive Session gibt, könnte man nach Rückfrage die Aufheben (Problem bei dir: normalerweise ist IP/Benutzer recht eindeutig, bei einem Terminalserver haben alle Benutzer die gleiche IP). Alternativ könnte ein Superuser auch Sessions löschen.
noch zu den Teilupdates: vermeide das Mischen von Stammdaten und Bewegungsdaten. Beispiel: Bei unserem Artikelstamm (Datenbankdesign > 20 Jahre) gibt die die Stammdaten und Felder für die letzte Bestellung und den Gesamtlagerstand usw. Nach aktuellen Sperrmechanismen ist das totaler Mist. Wenn jemand im Artikelstammblatt ist, und der Artikel inzwischen verkauft wird... Da gibt dann die Notwendigkeit einer logischen Sperre (nur für den Stammblattteil). Aber du hast sicher nicht > 1000 Cobolprogramme an der Datenbank hängen ;-) und kannst die DB vernünftig designen.
/Robert