Soll ich Zeilen in meiner Cloud-Datenbank sperren, während sie von einem Benutzer bearbeitet werden?

12

Ich erstelle eine Desktop-Anwendung, die die Daten in der Cloud beibehält. Ein Problem, das ich habe, besteht darin, ein Element in der Anwendung zu bearbeiten und es für eine Weile zu belassen, was dazu führt, dass die Daten veralten. Dies kann natürlich auch passieren, wenn 2 Personen gleichzeitig versuchen, dasselbe Objekt zu bearbeiten. Wenn sie ihre Bearbeitung abgeschlossen haben und die Daten speichern möchten, müsste ich entweder überschreiben, was derzeit in der Datenbank vorhanden ist, oder überprüfen, ob sie nach der letzten Änderung mit der Bearbeitung begonnen haben, und sie entweder zwingen, ihre Änderungen zu verwerfen, oder ihnen möglicherweise die Option zum Risiko geben Änderungen von jemand anderem überschreiben.

Ich habe darüber nachgedacht, Felder is_lockedund lock_timestampzur DB-Tabelle hinzuzufügen . Wenn ein Benutzer das Element bearbeitet, ändert sich die Zeile is_lockedin true und der Sperrzeitstempel wird auf die aktuelle Zeit gesetzt. Ich hätte dann etwas Zeit, für die die Sperre gehalten wird (zB 5 Minuten). Wenn eine andere Person versucht, das Objekt zu bearbeiten, wird eine Meldung angezeigt, dass das Objekt gesperrt ist und die Sperre automatisch abläuft. Wenn der Benutzer während der Bearbeitung die Sperre verlässt, läuft sie nach relativ kurzer Zeit automatisch ab. In diesem Fall wird der Benutzer gewarnt, dass die Sperre abgelaufen ist, und er muss die Bearbeitung nach dem Aktualisieren der Daten neu starten.

Wäre dies eine gute Methode, um das Überschreiben veralteter Daten zu verhindern? Ist es übertrieben (ich erwarte nicht, dass die Anwendung von mehr als ein paar Personen gleichzeitig auf einem einzigen Konto verwendet wird).

(Eine weitere Sorge, die ich habe, ist, dass 2 Personen ein Schloss für den gleichen Gegenstand erhalten. Ich glaube jedoch, dass dies eine Rennbedingung ist, mit der ich mich wohl fühle.)

yitzih
quelle
1
"Eine weitere Sorge, die ich habe, ist, dass 2 Personen eine Sperre für den gleichen Artikel erhalten. Ich glaube jedoch, dass dies eine Wettkampfbedingung ist, mit der ich zufrieden bin." Die Verwendung einer Datenbanktransaktion zum Erwerb der Sperre sollte solche Wettkampfbedingungen verhindern.
Jules
Die meisten Datenbank-Engines (zumindest relationale) unterstützen dies. Es ist ein in der RDBMS-Welt weit verbreitetes Konzept, und selbst "Spielzeug" -Datenbanken können es gut genug handhaben, vorausgesetzt, Sie möchten optimistische oder pessimistische Sperren. Wie auch immer, ich glaube nicht, dass Sie sich auf irgendeine Weise selbst bauen müssen: Überprüfen Sie die Optionen auf Ihrer Datenbank-Engine, um zu sehen, wie Sie damit arbeiten.
Jleach
Die Tatsache, dass Ihre Anwendung eine Desktop-Anwendung (ein Fat Client ) ist, macht keinen großen Unterschied. Es kann wie eine hochverfügbare Serveranwendung mit mehreren Instanzen entworfen werden.
Hosam Aly

Antworten:

19

Eine Sache, die Ihnen hier helfen wird, ist die Terminologie. Was Sie hier beschreiben, heißt "pessimistisches Sperren". Die Hauptalternative zu diesem Ansatz ist "optimistisches Sperren". Beim pessimistischen Sperren muss jeder Akteur den Datensatz vor dem Aktualisieren sperren und die Sperre aufheben, wenn die Aktualisierung abgeschlossen ist. Beim optimistischen Sperren wird davon ausgegangen, dass niemand den Datensatz aktualisiert, und es wird versucht. Das Update schlägt fehl, wenn der Datensatz von einem anderen Akteur geändert wurde.

Optimistisches Sperren ist im Allgemeinen vorzuziehen, wenn die Chance, dass zwei Akteure zur gleichen Zeit dasselbe aktualisieren, gering ist. Pessimistisch wird normalerweise verwendet, wenn diese Chance hoch ist oder Sie wissen müssen, dass Ihr Update erfolgreich sein kann, bevor Sie beginnen. Nach meiner Erfahrung ist optimistisches Sperren fast immer vorzuziehen, da es viele Probleme gibt, die mit pessimistischem Sperren verbunden sind. Eines der größten Probleme wird in Ihrer Frage angesprochen. Benutzer können einen Datensatz zum Bearbeiten sperren und dann zum Mittagessen gehen. Ihre Abschwächung wird dabei helfen, aber die Benutzererfahrung wird nicht besser sein als der optimistische Ansatz und wird wahrscheinlich viel schlechter sein. Zum Beispiel öffnet ein Benutzer einen Datensatz, beginnt mit der Aktualisierung und sein Chef erscheint an seinem Schreibtisch. Ein anderer Benutzer versucht, den Datensatz zu bearbeiten. Es ist abgeschlossen. Der zweite Benutzer versucht es weiter und nach 5 Minuten Die Sperre läuft ab und der zweite Benutzer aktualisiert den Datensatz. Der erste Benutzer kehrt zum Bildschirm zurück, versucht zu speichern und erhält die Meldung, dass er seine Sperre verloren hat. Jetzt, im selben Szenario mit dem gleichen Verhalten, außer der Verwendung von optimistischem Sperren, ist die Erfahrung des ersten Benutzers ziemlich gleich, aber der zweite Benutzer wartet keine 5 Minuten.

Das Schema, das Sie entwerfen, würde durch das Implementieren einer optimistischen Sperre für den Sperrwert erheblich verbessert werden. Ich bin jedoch der Meinung, dass eine optimistische Sperre für die gesamte Sache wahrscheinlich in Ordnung ist und Sie das Feld is_locked entfernen können.

Sie geben nicht an, welche Cloud-Datenbank Sie verwenden. Sie sollten sich wahrscheinlich die Funktionen ansehen, um festzustellen, ob hierfür integrierte Funktionen vorhanden sind, bevor Sie Ihre eigene Lösung implementieren.

Hier ist das Grundrezept: Statt eines is_locked-Feldes ein Versionsnummernfeld. Wenn Sie den Datensatz abrufen, rufen Sie die aktuelle Version des Datensatzes ab. Wenn Sie eine Aktualisierung durchführen, wird die Aktualisierung von dem Versionsfeld abhängig gemacht, das mit dem abgerufenen Feld übereinstimmt, und bei Erfolg erhöht. Wenn die Version nicht übereinstimmt, hat das Update keine Auswirkung und Sie melden es als Fehler.

JimmyJames
quelle
Dies ist eine sehr hilfreiche Antwort. Können Sie erklären, warum pessimistisches Sperren bei einer geringen Wahrscheinlichkeit von "Kollisionen" nicht empfohlen wird? Liegt es nur daran, dass Sie erst in die Datenbank gehen müssen, um mit der Bearbeitung zu beginnen, oder an der zusätzlichen Komplexität oder einem anderen Grund? Vielen Dank!
Yitzih
3
Einige Lesevorschläge: Fowler et al., Patterns of Enterprise Application Architecture . Zu dieser Frage gibt es ein ganzes Kapitel, in dem alle Optionen und Gründe für ihre Auswahl ausführlich erörtert werden.
Jules
2
@ Jimmy - Ihre Antwort ist in Ordnung. In einigen Fällen kann es nicht ausreichen, einen Fehler zurückzumelden. Stellen Sie sich einen Fall vor, in dem ein Benutzer einige Minuten damit verbringt, einen Datensatz zu aktualisieren. In diesem Fall kann es sein, dass ein Fehlschlagen nicht ausreicht. Unter Umständen möchten Sie dem Benutzer die Möglichkeit geben, die Änderungen im Flug mit den Änderungen des anderen Benutzers zusammenzuführen. Ich sollte optimistische Sperren gesagt hat , können Konfliktlösung erfordern je nach Ihren Anforderungen.
Jon Raynor
3
Erwähnenswert ist, dass das pessimistische Sperren dem Kunden viel einfacher zu erklären ist. Wenn Sie eine Nachricht schreiben, dass der Client nicht auf den Datensatz zugreifen kann, weil er gerade von einem anderen bearbeitet wird, versteht der Client beide einwandfrei und akzeptiert ihn im Allgemeinen. Wenn Sie dem Client stattdessen nach dem Speichern mitteilen, dass das Speichern nicht möglich war, weil es bereits von einem anderen Benutzer (7/10) aktualisiert wurde, ist der Client frustriert und / oder erwartet Erklärungen für dieses seltsame Programmverhalten.
Neil
2
@Neil Das stimmt und ich denke, es ist oft der Grund, warum pessimistisches Sperren verwendet wird, wenn optimistisch angemessener ist. Oft ist es aufgrund des Workflows sehr unwahrscheinlich, dass es zu einer Kollision kommt.
JimmyJames
0

Aus der Antwort von @ JimmyJames können wir ersehen , wie sich die Frage wirklich auf das Benutzererlebnis auswirkt .

Es hängt alles vom Kontext ab. Wie viel Zeit und Mühe ist erforderlich, um einen Datensatz zu aktualisieren? Wie oft möchten mehrere Benutzer dasselbe Dokument aktualisieren?

Wenn Ihre Benutzer normalerweise ein paar Sekunden benötigen, um den Datensatz zu aktualisieren, und es kaum Konflikte gibt, ist eine optimistische Sperrung wahrscheinlich der richtige Weg. Im schlimmsten Fall muss ein Benutzer noch einige Sekunden, möglicherweise bis zu einer Minute, aufwenden, um ein Dokument zu aktualisieren.

Wenn Ihr Dokument sehr umstritten, aber gut strukturiert ist, können Sie es möglicherweise zulassen, dass einzelne Felder in Schritten von 30 Sekunden gesperrt werden. Dabei wird ein Zeitgeber oder eine unauffällige Benachrichtigung angezeigt, damit die Sperre erweitert werden kann.

Wenn Ihre Benutzer jedoch viel Zeit oder Mühe aufwenden, sollten Sie andere Ansätze in Betracht ziehen. Ist Ihre Akte gut strukturiert? Können Sie den Benutzern einen Vergleich (einen Unterschied) zwischen der Version auf dem Server und der Version anzeigen, die sie speichern möchten? Können Sie die Unterschiede hervorheben? Können Sie sie lassen verschmelzen die Änderungen? Denken Sie an die Erfahrung, die Sie mit Ihren Versionsverwaltungswerkzeugen machen möchten. Sie wollen wirklich nicht gezwungen sein, den ganzen Code noch einmal zu schreiben!

Weitere Anregungen finden Sie in Google Text & Tabellen. Vielleicht können Sie den Benutzern eine Benachrichtigung anzeigen, dass eine neue Version gespeichert wurde. Vielleicht können Sie ihnen zeigen, wie viele Personen die Akte geöffnet haben, damit sie zu einem weniger strittigen Zeitpunkt zurückkehren können.

Hosam Aly
quelle