Autorwww.itsvse.com @小渣渣 ! Fügen Sie die Basisdaten erfolgreich ein! Das Testen der ConcurrencyCheck-Funktion ist abgeschlossen Update erfolgreich! Anmerkung 1 Das Update ist außergewöhnlich! Anmerkung 2, abnormale Informationen! Die Store Update-, Insert- oder Delete-Anweisung beeinflusste eine unerwartete Anzahl von Zeilen (0). Entitäten könnten verändert oder gelöscht worden sein, da Entitäten geladen wurden. Siehe http://go.microsoft.com/fwlink/?LinkId=472540 für Informationen zum Verständnis und Umgang mit Ausnahmen der optimistischen Nebenläufigkeit.
Teste den Unterschied zwischen Timestamp und Concurrency Check UpdateTab1-Update erfolgreich! Name 1 UpdateTab2-Update erfolgreich! Name 1 UpdateTab2-Update ist ungewöhnlich! Name 2, abnormale Informationen! Die Store Update-, Insert- oder Delete-Anweisung beeinflusste eine unerwartete Anzahl von Zeilen (0). Entitäten könnten verändert oder gelöscht worden sein, da Entitäten geladen wurden. Siehe http://go.microsoft.com/fwlink/?LinkId=472540 für Informationen zum Verständnis und Umgang mit Ausnahmen der optimistischen Nebenläufigkeit. UpdateTab1-Update erfolgreich! Name 2
【TimeStamp】 Die TimeStamp-Funktion kann auf die Feldklasse angewendet werden, die nur eine Byte-Array-Eigenschaft besitzt, und diese Funktion setzt den tiemStamp-Typ auf die Spalte. Bei gleichzeitigen Überprüfungen verwendet Code-First automatisch dieses TimeStamp-Typfeld.
【ConcurrencyCheck】 Die ConcurrencyCheck-Funktion kann auf die Eigenschaften einer Domänenklasse angewendet werden. Wenn EF eine Aktualisierungsoperation durchführt, setzt Code-First den Wert der Spalte in die where-Condition-Anweisung, und Sie können diese CurrencyCheck-Funktion nutzen, um die vorhandenen Spalten für die Nebenfeldigkeitsprüfung zu verwenden, anstatt eine separate TimeStamp-Spalte für Nebenläufigkeitsprüfungen zu verwenden.
Beginnen wir damit, ein neues Kontextobjekt zu erstellen, um den Unterschied zwischen Timestamp und ConcurrencyCheck bei der Nebenläufigkeitsverarbeitung zu demonstrieren!
Hier ist der Code für den Kontext:
Schauen wir uns die Spalten der Datenbank wie folgt an:
Wir werden feststellen, dass Tab1 und Tab2 die Spalten Id, Name und Bemerkung haben, und Tab2 mehr RowVersion-Spalten als Tab 1.
Hängen Sie zuerst den Testcode an:
【ConcurrencyCheck Principle】
Wir haben die ConcurrencyCheck-Funktion zur Remark-Eigenschaft von Tab1 hinzugefügt,
Wenn wir den Namensattributwert derselben Daten zur gleichen Zeit aktualisieren, wird keine Ausnahme ausgelöst!
Generiere SQL-Anweisungen:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Name] = @0 WOBEI (([Id] = @1) UND ([Bemerkung] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name1',@1=1,@2=N'Note1' exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Name] = @0 WOBEI (([Id] = @1) UND ([Bemerkung] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'name2',@1=1,@2=N'note1' Wenn wir den Remark-Eigenschaftswert derselben Daten zur gleichen Zeit aktualisieren, werden eine Ausnahme ausgelöst!
Generiere SQL-Anweisungen:
exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Anmerkung] = @0 WOBEI (([Id] = @1) UND ([Bemerkung] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note1',@1=1,@2=N'Note' exec sp_executesql N'UPDATE [dbo]. [Tab1] SET [Anmerkung] = @0 WOBEI (([Id] = @1) UND ([Bemerkung] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Note 2',@1=1,@2=N'Note' Wir können feststellen, dass wir, wenn wir dasselbe Datenstück mit ID 1 zur gleichen Zeit nehmen, den Wert des Remark-Attributs erhalten, und beim Aktualisieren des Remark-Attributs verwenden wir Remark als Aktualisierungsbedingung.
Die erste SQL-Anweisung kann erfolgreich aktualisiert werden, dann wird die Bemerkung in "Note 1" geändert, und wenn die zweite SQL-Anweisung aktualisiert wird, scheitert das Update, weil sich der Wert der Bemerkung geändert hat.
【Zeitstempelprinzip】
Wir haben eine RowVersion-Eigenschaft zu Tab2 hinzugefügt (du kannst jeden Namen nehmen) und die Timestamp-Funktion hinzugefügt!!
Wenn wir den Namenswert derselben Daten gleichzeitig aktualisieren, das erste Update erfolgreich ist, das zweite Update fehlschlägt und eine Ausnahme ausgelöst wird – schauen wir uns den generierten SQL-Code an!
exec sp_executesql N'UPDATE [dbo]. [Tab2] SET [Name] = @0 WOBEI ((([Id] = @1) UND ([RowVersion] = @2)) UND ([Bemerkung] = @3)) AUSWÄHLEN [ZeileVersion] VON [dbo]. [Tab2] WOBEI @@ROWCOUNT > 0 UND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binär(8),@3 nvarchar(max) ',@0=N'Name1',@1=1,@2=0x00000000000007D1,@3=N'Note' exec sp_executesql N'UPDATE [dbo]. [Tab2] SET [Name] = @0 WOBEI ((([Id] = @1) UND ([RowVersion] = @2)) UND ([Bemerkung] = @3)) AUSWÄHLEN [ZeileVersion] VON [dbo]. [Tab2] WOBEI @@ROWCOUNT > 0 UND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binär(8),@3 nvarchar(max) ',@0=N'name2',@1=1,@2=0x00000000000007D1,@3=N'Note' Beim Ausführen der zweiten SQL-Anweisung, weil die Daten der where-Bedingung nicht mehr gefunden werden können, schlägt das Update fehl und eine Ausnahme wird ausgelöst!!
Nachdem die erste SQL-Anweisung erfolgreich ausgeführt wurde, ändert sich der Wert von RowVersion, wie in der untenstehenden Abbildung gezeigt:
RowsVersion ist ein Zeitstempel
Workaround für fehlende Updates
Konzept der fehlenden Updates: Wenn Benutzer eine Datenzeile gleichzeitig ändern, lesen sie zuerst die Daten, setzen sie zur Änderung auf das Frontend und reichen die Daten dann nach der Änderung ein, sodass die zuletzt eingereichten Daten die zuvor eingereichten Daten überschreiben, was zum verlorenen Update führt.
Kurz gesagt, hier sind Möglichkeiten, den Verlust von Updates zu vermeiden:
Verwenden Sie den Zeitstempel RowsVersion.
Wenn eine Zeile mit dem Wert vor dem Lesen inkonsistent ist, bedeutet das, dass eine andere Transaktion diese Spalte aktualisiert hat, sodass diese Spalte nicht aktualisiert werden kann und so der Verlust von Aktualisierungen verhindert wird.
Zum Schluss fügen Sie den Quellcode an:
CodeFirstDemo.rar
(4.94 KB, Anzahl der Downloads: 13)
|