Bevorzugter Entwurf von Datenbank- / Webapp-Concurrency, wenn mehrere Benutzer dieselben Daten bearbeiten können

8

Ich habe eine ASP.NET C # Business-Webanwendung, die intern verwendet wird. Ein Problem, mit dem wir konfrontiert werden, ist, dass das ursprüngliche Design die Parallelitätsprüfung nicht berücksichtigt hat. Jetzt greifen mehrere Benutzer auf die gleichen Daten zu und überschreiben andere Benutzeränderungen. Meine Frage ist also - benutzen Webapps normalerweise ein pessimistisches oder optimistisches Nebenläufersystem? Was treibt die Präferenz, eine über die andere zu verwenden, und welche Designaspekte müssen berücksichtigt werden?

Ich stehe derzeit auf eine optimistische Gleichzeitigkeitsprüfung, da sie nachsichtiger zu sein scheint, aber ich bin besorgt über das Potenzial für mehrere Änderungen, die im Widerspruch zueinander stehen würden.

Danke!

    
rijipooh 07.05.2009, 16:21
quelle

4 Antworten

3

Optimistisches Sperren.
Pessimistisch ist schwieriger zu implementieren und führt zu Problemen in einer Web-Umgebung. Durch welche Aktion wird die Sperre aufgehoben und der Browser geschlossen? Die Sitzung für eine Auszeit verlassen? Was ist, wenn sie dann ihre Änderungen speichern?

Sie geben nicht an, welche Datenbank Sie verwenden. MS SQL Server hat einen Zeitstempel-Datentyp. Es hat jedoch nichts mit der Zeit zu tun. Es ist normalerweise eine Zahl, die jedes Mal geändert wird, wenn die Zeile aktualisiert wird. Sie müssen nichts tun, um sicherzustellen, dass es geändert wird, Sie müssen es nur überprüfen. Sie können ähnliche Ergebnisse erzielen, indem Sie ein Datum / eine Uhrzeit verwenden, die zuletzt geändert wurde, wie es von @KM vorgeschlagen wird. Aber das bedeutet, dass Sie daran denken müssen, es jedes Mal zu ändern, wenn Sie die Zeile aktualisieren. Wenn Sie datetime verwenden, müssen Sie einen Datentyp mit ausreichender Genauigkeit verwenden, um sicherzustellen, dass der Wert nicht geändert wird, wenn er sollte. Zum Beispiel speichert jemand eine Zeile, dann liest jemand sie, dann passiert eine weitere Speicherung, aber das modifizierte Datum / die geänderte Zeit bleibt unverändert. Ich würde Timestamp verwenden, es sei denn, es war eine Anforderung, Datum der letzten Änderung auf Datensätzen zu verfolgen.

Um es zu überprüfen, können Sie tun, was @KM vorschlägt und es in die where-Klausel der update-Anweisung aufnehmen. Oder Sie können eine Transaktion starten, den Zeitstempel überprüfen, wenn alles gut ist, die Aktualisierung durchführen, dann die Transaktion festschreiben, wenn nicht, dann einen Fehlercode oder Fehler zurückgeben.

Das Halten von Transaktionen (wie von @le dorfier vorgeschlagen) ähnelt dem pessimistischen Sperren, aber die Menge der gesperrten Daten kann mehr als eine Zeile sein. Die meisten RDBMs werden standardmäßig auf Seitenebene gesperrt. Sie werden auch auf die gleichen Probleme stoßen wie beim pessimistischen Sperren.

Sie erwähnen in Ihrer Frage, dass Sie sich über widersprüchliche Updates Sorgen machen. Das wird die Verriegelung sicher verhindern. Sowohl optimistischer als auch pessimistischer Wille, wenn er richtig umgesetzt wird, verhindern genau das.

    
pipTheGeek 07.05.2009, 17:16
quelle
3

Ich stimme der ersten Antwort oben zu, wir versuchen optimistisches Sperren zu verwenden, wenn die Wahrscheinlichkeit von Kollisionen ziemlich gering ist. Dies kann einfach mit einer LastModifiedDate-Spalte oder einer Inkrementierung einer Version-Spalte implementiert werden. Wenn Sie sich über die Häufigkeit von Kollisionen nicht im Klaren sind, melden Sie sie irgendwo, damit Sie sie im Auge behalten können. Wenn sich Ihre Datensätze immer im Bearbeitungsmodus befinden, können die Modi "Ansicht" und "Bearbeiten" dazu beitragen, die Anzahl der Kollisionen zu reduzieren (vorausgesetzt, Sie laden die Daten neu, wenn Sie den Bearbeitungsmodus aufrufen).

Wenn die Kollisionen immer noch hoch sind, ist das pessimistische Sperren in Web-Apps schwieriger zu implementieren, aber definitiv möglich. Wir hatten einen guten Erfolg mit "Leasing" -Rekorden (Sperrung mit einer Zeitüberschreitung) ... ähnlich der 2-Minuten-Warnung, die Sie bekommen, wenn Sie Tickets bei TicketMaster kaufen. Wenn ein Benutzer in den Bearbeitungsmodus wechselt, legen wir einen Datensatz mit einer Zeitüberschreitung von N Minuten in die "lock" -Tabelle. Anderen Benutzern wird eine Nachricht angezeigt, wenn sie versuchen, einen Datensatz mit einer aktiven Sperre zu bearbeiten. Sie könnten auch ein Keep-Alive für lange Formulare implementieren, indem Sie die Lease für jedes Postback der Seite oder sogar für einen Ajax-Timer erneuern. Es gibt auch keinen Grund, warum Sie dies nicht mit einer oben erwähnten optimistischen Standardsperre unterstützen könnten.

Viele Apps benötigen eine Kombination beider Ansätze.

    
chaiwalla 07.05.2009 17:28
quelle
1

Hier ist eine einfache Lösung für viele Leute, die an denselben Datensätzen arbeiten.

Wenn Sie die Daten laden, erhalten Sie das letzte Änderungsdatum, verwenden wir LastChgDate auf unseren Tabellen

Wenn Sie die Daten speichern (aktualisieren), fügen Sie "AND LastChgDate = previousLoadedLastChgDate" zur WHERE-Klausel hinzu. Wenn die Zeilenanzahl bei der Aktualisierung = 0 ist, geben Sie einen Fehler ein, bei dem "jemand anders diese Daten bereits gespeichert hat", und führen Sie einen Rollback durch, andernfalls werden die Daten gespeichert.

Ich verwende die obige Logik im Allgemeinen nur für Header-Tabellen und nicht für die Details-Tabellen, da sie alle in einer Transaktion sind.

    
KM. 07.05.2009 17:04
quelle
0

Ich nehme an, dass Sie das Problem "verlorenes Update" haben.

Um dem als Faustregel zu begegnen, verwende ich pessimistisches Sperren, wenn die Wahrscheinlichkeit einer Kollision hoch ist (oder Transaktionen sind kurzlebig) und optimistisches Sperren, wenn die Wahrscheinlichkeit einer Kollision gering ist (oder Transaktionen sind langlebig, oder Ihre Geschäftsregeln umfassen mehrere Transaktionen).

Sie müssen wirklich sehen, was auf Ihre Situation zutrifft und einen Urteilsspruch machen.

    
Glen 07.05.2009 16:27
quelle