Bearbeiten von Datenbankaufzeichnungen von mehreren Benutzern

stimmen
23

Ich habe Datenbanktabellen entworfen (normalisieren, auf einem MS SQL Server) und erstellte Front eine eigenständige Windows für eine Anwendung beenden, die von einer Handvoll von Benutzern verwendet werden, um Informationen hinzufügen und bearbeiten. Wir werden eine Web-Schnittstelle hinzufügen, unsere Produktionsfläche zu einem späteren Zeitpunkt zu ermöglichen, die Suche accross.

Ich bin besorgt, dass, wenn zwei Benutzer die Bearbeitung der gleichen Aufzeichnung starten dann das letzte, das Update zu begehen wäre die ‚Gewinner‘ und wichtige Informationen verloren gehen. Eine Reihe von Lösungen in den Sinn kommen, aber ich bin nicht sicher, ob ich einen größeren Kopfschmerzen schaffen werde.

  1. Nichts tun und hoffen , dass zwei Benutzer nie den gleichen Datensatz zur gleichen Zeit der Bearbeitung gehen werden. - Könnte nie happed aber was , wenn es tut?
  2. Bearbeiten von Routine konnte eine Kopie der Originaldaten speichern sowie die Updates und dann vergleichen , wenn der Benutzer die Bearbeitung beendet ist. Wenn sie zeigen Benutzer unterscheiden und zu aktualisieren comfirm - Würden zwei Kopien von Daten erfordern gespeichert werden.
  3. In letzte Aktualisierung DATETIME- Spalte und überprüfen Sie es übereinstimmt , wenn wir aktualisieren, wenn nicht , dann Unterschiede zeigen. - erfordert neue Spalte in jedem der entsprechenden Tabellen.
  4. Erstellen Sie eine Tabelle , die Bearbeitung registriert , wenn Benutzer starten einen Datensatz bearbeiten , die überprüft werden und verhindern , dass andere Benutzer die Bearbeitung denselben Datensatz. - würde carful Gedanken Programmablauf erfordern Deadlocks und Aufzeichnungen zu verhindern gesperrt immer , wenn ein Benutzer aus dem Programm abstürzt.

Gibt es bessere Lösungen oder sollte ich gehen für eine von ihnen?

Veröffentlicht am 03/08/2008 um 22:23
quelle vom benutzer
In anderen Sprachen...                            


8 antworten

stimmen
12

Wenn Sie selten Kollisionen erwarten optimistisch Concurrency ist wahrscheinlich die beste Wahl.

Scott Mitchell schrieb ein umfassendes Tutorial über die Umsetzung dieses Muster: Die
Umsetzung optimistisch Concurrency

Beantwortet am 03/08/2008 um 22:31
quelle vom benutzer

stimmen
2

Ein klassischer Ansatz ist wie folgt:

  • fügen Sie ein boolean Feld, „gesperrt“ auf jeden Tisch.
  • setzen Sie diese standardmäßig auf false.
  • wenn ein Benutzer die Bearbeitung beginnt, tun Sie dies:

    • sperren Sie die Zeile (oder die gesamte Tabelle, wenn Sie die Zeile nicht sperren kann)
    • Besuche die Flagge auf der Zeile, die Sie bearbeiten möchten
    • wenn das Flag gilt dann
      • informiert die Benutzer, dass sie diese Zeile im Moment nicht bearbeiten
    • sonst
      • das Kennzeichen auf wahr
    • die Sperre

    • wenn die Aufzeichnung zu speichern, stellen Sie die Flagge zurück auf false

Beantwortet am 01/10/2008 um 09:53
quelle vom benutzer

stimmen
1

-first erstellen eingereicht (Aktualisierungszeit) letzte Änderung Aufzeichnung speichern -wenn jeder Benutzer Datensatz speichern Auswahlzeit wählen, vergleichen, zwischen Auswahlzeit und Aktualisierungszeit Feld if (Aktualisierungszeit)> (wählen Zeit), dass ein anderer Benutzer aktualisieren diesen Rekord bedeuten nach wählen Aufzeichnung

Beantwortet am 14/07/2016 um 11:23
quelle vom benutzer

stimmen
1

SELECT FOR UPDATE und Äquivalente sind gut Bereitstellen Sie die Sperre für eine mikroskopische Menge an Zeit halten, aber für eine makroskopische Menge (zB der Benutzer die Daten geladen und nicht gedrückt hat ‚Speichern‘ sollten Sie Parallelität wie oben verwenden. (Welche ich denke immer, ist falsch benannt - es ist pessimistischer als ‚letzter Schriftsteller gewinnt‘, das ist in der Regel die einzige andere Alternative in Betracht gezogen).

Beantwortet am 01/10/2008 um 06:39
quelle vom benutzer

stimmen
1

Eine weitere Option ist zu prüfen, dass die Werte in den Datensatz, den Sie verändern sich die immer noch die gleichen sind, wie sie waren, als Sie begonnen haben:

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

(Anzeige des customer_nm Feldes 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 nicht um eine neue Spalte zu Ihrer Tabelle hinzuzufügen (und halten sie auf dem Laufenden), aber Sie haben ausführlichere SQL - Anweisungen erstellen und übergeben Sie neue und alte Felder auf die gespeicherte Prozedur.

Es hat auch den Vorteil, dass Sie nicht die Datensätze sind Sperren - weil wir alle wissen, dass Datensätze gesperrt wird am Ende zu bleiben, wenn sie nicht sein sollte ...

Beantwortet am 13/08/2008 um 23:32
quelle vom benutzer

stimmen
1

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

Der SQL Server - Äquivalent ist die SELECTAnweisung Hinweis UPDLOCK.

Siehe SQL Server - Online für weitere Informationen.

Beantwortet am 04/08/2008 um 22:54
quelle vom benutzer

stimmen
0

Bei mir, dem besten Weg, habe ich eine Spalte lastupdate (timetamp Datentyp). wenn Auswahl und Aktualisierung nur diesen Wert zu vergleichen, ein weiterer Fortschritt dieser Lösung ist, dass Sie in dieser Spalte die Zeitdaten ändern muss auf die Spur verwenden können. Ich denke, es ist nicht gut, wenn man nur ein colum wie isLock für den Check-Update erstellen.

Beantwortet am 24/06/2011 um 08:14
quelle vom benutzer

stimmen
0

Die Datenbank wird dies für Sie tun. Schauen Sie sich „wählen ... for update“, die nur für diese Art der Sache ausgelegt ist. Es wird Ihnen eine Schreibsperre auf den ausgewählten Zeilen, die Sie dann begehen oder rückgängig zu machen.

Beantwortet am 04/08/2008 um 03:30
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more