sql server - Bearbeiten von Datenbankeinträgen durch mehrere Benutzer

Translate

Ich habe Datenbanktabellen (normalisiert, auf einem MS SQL-Server) entworfen und ein eigenständiges Windows-Frontend für eine Anwendung erstellt, die von einer Handvoll Benutzern zum Hinzufügen und Bearbeiten von Informationen verwendet wird. Wir werden eine Weboberfläche hinzufügen, um zu einem späteren Zeitpunkt die Suche in unserem Produktionsbereich zu ermöglichen.

Ich mache mir Sorgen, dass, wenn zwei Benutzer denselben Datensatz bearbeiten, der letzte, der das Update festschreibt, der "Gewinner" ist und wichtige Informationen verloren gehen könnten. Eine Reihe von Lösungen kommen mir in den Sinn, aber ich bin mir nicht sicher, ob ich größere Kopfschmerzen verursachen werde.

  1. Tun Sie nichts und hoffen Sie, dass zwei Benutzer niemals denselben Datensatz gleichzeitig bearbeiten.- Könnte nie passiert sein, aber was ist, wenn es passiert?
  2. Die Bearbeitungsroutine kann eine Kopie der Originaldaten sowie der Aktualisierungen speichern und dann vergleichen, wenn der Benutzer die Bearbeitung abgeschlossen hat. Wenn sie sich unterscheiden, zeigen Sie den Benutzer an und bestätigen Sie das Update- Es müssten zwei Kopien der Daten gespeichert werden.
  3. Fügen Sie die zuletzt aktualisierte Spalte DATETIME hinzu und überprüfen Sie, ob sie bei der Aktualisierung übereinstimmt. Wenn nicht, zeigen Sie Unterschiede an.- erfordert eine neue Spalte in jeder der relevanten Tabellen.
  4. Erstellen Sie eine Bearbeitungstabelle, die registriert, wann Benutzer mit der Bearbeitung eines Datensatzes beginnen, der überprüft wird, und verhindern, dass andere Benutzer denselben Datensatz bearbeiten.- würde sorgfältige Überlegungen zum Programmablauf erfordern, um zu verhindern, dass Deadlocks und Datensätze gesperrt werden, wenn ein Benutzer aus dem Programm ausfällt.

Gibt es bessere Lösungen oder sollte ich mich für eine entscheiden?

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Wenn Sie seltene Kollisionen erwarten,Optimistische Parallelitätist wahrscheinlich die beste Wahl.

Scott Mitchell hat ein umfassendes Tutorial zur Implementierung dieses Musters geschrieben:
Optimistische Parallelität implementieren

Quelle
AJ.
Translate

Ein klassischer Ansatz lautet wie folgt:

  • Fügen Sie jeder Tabelle ein boolesches Feld hinzu, das "gesperrt" ist.
  • Setzen Sie dies standardmäßig auf false.
  • Wenn ein Benutzer mit der Bearbeitung beginnt, gehen Sie folgendermaßen vor:

    • Sperren Sie die Zeile (oder die gesamte Tabelle, wenn Sie die Zeile nicht sperren können).
    • Aktivieren Sie das Flag in der Zeile, die Sie bearbeiten möchten
    • if the flag is true then
      • Informieren Sie den Benutzer, dass er diese Zeile derzeit nicht bearbeiten kann
    • else
      • Setzen Sie das Flag auf true
    • Lassen Sie das Schloss los

    • Setzen Sie beim Speichern des Datensatzes das Flag wieder auf false

Quelle
Julian Lee
Translate

SELECT FOR UPDATE und Äquivalente sind gut, vorausgesetzt, Sie halten die Sperre für eine mikroskopische Zeitspanne, aber für eine makroskopische Zeitspanne (z. B. wenn der Benutzer die Daten geladen hat und nicht auf "Speichern" geklickt hat, sollten Sie wie oben optimistische Parallelität verwenden Ich denke immer, dass es falsch benannt ist - es ist pessimistischer als "Der letzte Schriftsteller gewinnt", was normalerweise die einzige andere Alternative ist, die in Betracht gezogen wird.)

Quelle
Translate

@ Mark Harrison: SQL Server unterstützt diese Syntax nicht (SELECT ... FOR UPDATE).

Das SQL Server-Äquivalent ist dasSELECTAnweisungshinweisUPDLOCK.

SehenSQL Server-Online-Bücherfür mehr Informationen.

Quelle
Translate

- Erstes Erstellen einer Datei (Aktualisierungszeit) zum Speichern des letzten Aktualisierungsdatensatzes. - Wenn ein Benutzer einen Auswahldatensatz speichert, wählen Sie die Auswahlzeit aus. Vergleichen Sie zwischen Auswahlzeit und Aktualisierungszeitfeld, wenn (Aktualisierungszeit)> (Auswahlzeit) bedeutet, dass ein anderer Benutzer diesen Datensatz nach der Auswahl aktualisiert Aufzeichnung

Quelle
Guy
Translate

Eine andere Möglichkeit besteht darin, zu testen, ob die Werte in dem Datensatz, den Sie ändern, immer noch dieselben sind wie zu Beginn:

SELECT 
    customer_nm,
    customer_nm AS customer_nm_orig
FROM demo_customer
WHERE customer_id = @p_customer_id

(Zeigen Sie das Feld customer_nm an und der Benutzer ändert es.)

UPDATE demo_customer
SET customer_nm = @p_customer_name_new
WHERE customer_id = @p_customer_id
AND customer_name = @p_customer_nm_old

IF @@ROWCOUNT = 0
    RAISERROR( 'Update failed: Data changed' );

Sie müssen Ihrer Tabelle keine neue Spalte hinzufügen (und auf dem neuesten Stand halten), aber Sie müssen ausführlichere SQL-Anweisungen erstellen und übergebenNeuundaltFelder zur gespeicherten Prozedur.

Es hat auch den Vorteil, dass Sie die Datensätze nicht sperren - weil wir alle wissen, dass Datensätze gesperrt bleiben, wenn sie nicht gesperrt werden sollten ...

Quelle
Translate

Die Datenbank erledigt dies für Sie. Schauen Sie sich "select ... for update" an, das genau für diese Art von Dingen entwickelt wurde. Sie erhalten eine Schreibsperre für die ausgewählten Zeilen, die Sie dann festschreiben oder zurücksetzen können.

Quelle
Translate

Bei mir ist der beste Weg, ein Spalten-Lastupdate (Zeitstempeldatentyp) zu haben. Wenn Sie diesen Wert auswählen und aktualisieren, vergleichen Sie einfach diesen Wert. Ein weiterer Fortschritt dieser Lösung besteht darin, dass Sie diese Spalte verwenden können, um die Zeit zu verfolgen, in der sich Daten geändert haben. Ich denke, es ist nicht gut, wenn Sie nur eine Spalte wie isLock für das Check-Update erstellen.

Quelle