Ich entwickle derzeit ein Online-Auktionssystem unter Verwendung von ASP.NET 3.5 und SQLServer 2008. Ich habe den Punkt in der Entwicklung erreicht, wo ich sicherstellen muss, dass mein System das Concurrency-Problem sinnvoll behandelt, wenn:
Zwei Personen - Geraldine und John - wollen auf dasselbe Auktionsobjekt bieten, das derzeit für 50 £ angeboten wird. Geraldine gibt ein Gebot von £ 55 und John gibt ein Gebot von £ 52. Das System hat jetzt zwei Kopien der Seite 'submit_bid.aspx' ausgeführt; Jede Kopie der Seite prüft, ob ihr Gebot hoch genug ist. Beide sehen, dass es ist, und sie reichen die Gebote ein. Wenn das Gebot von John zuerst durchgeht, beträgt der Auktionspreis derzeit £ 55 und einen Moment später wird es durch ein Gebot von £ 52 ersetzt.
Ich muss die Auktionszeilen sperren, bis der aktuelle Gebotspreis aktualisiert wird, bevor Sie anderen Bietern erlauben, den aktuellen Gebotspreis zu prüfen und ein neues Gebot abzugeben.
Meine Frage ist: Was ist der beste Weg, dies mit T-SQL und / oder ADO.NET zu tun?
Ich habe derzeit eine AuctionItem-Tabelle, die folgende Felder enthält (plus andere Felder, die ich der Kürze halber nicht aufgenommen habe):
%Vor%Ich habe einige Nachforschungen angestellt und das folgende T-SQL (Pseudocode-ish) gefunden:
%Vor% Ich habe auch gelesen, dass ich, wenn ich SET LOCK_TIMEOUT
einschließe, auch die Anzahl der fehlgeschlagenen gleichzeitigen Aktualisierungen reduzieren kann. Zum Beispiel:
... bewirkt, dass eine gleichzeitige Aktualisierung 1000 Millisekunden lang wartet, bis eine Sperre ausgelöst wird. Ist dies die beste Vorgehensweise?
Ich habe den obigen Vorschlag von Alex K befolgt und eine "Bid History" implementiert. Funktioniert gut. Danke Alex K.
Quelle: "chrisrlong", Ссылка
Hier sind die Methoden, die zur Behandlung von Parallelitätsproblemen bei mehreren Benutzern verwendet werden:
Nichts (nicht wünschenswert)
tunBenutzer 2 hat die Änderungen, die Benutzer 1 vorgenommen hat, jetzt überschrieben. Sie sind komplett weg, als wären sie nie passiert. Dies wird als "verlorenes Update" bezeichnet.
Pessimistisches Sperren (Sperren Sie den Datensatz, wenn er gelesen wird.)
Das Problem mit dem verlorenen Update ist gelöst. Das Problem bei diesem Ansatz ist Nebenläufigkeit. Benutzer 1 sperrt einen Datensatz, den sie möglicherweise nie aktualisieren. Benutzer 2 kann den Datensatz nicht einmal lesen, weil er beim Lesen auch eine exklusive Sperre wünscht. Dieser Ansatz erfordert viel zu viel exklusives Sperren, und die Sperren leben viel zu lange (oft über Benutzerkontrolle - ein absolut no-no). Dieser Ansatz ist fast nie implementiert.
Optimistische Sperre verwenden.
Optimistisches Sperren verwendet beim Lesen keine exklusiven Sperren. Stattdessen wird während des Updates eine Überprüfung durchgeführt, um sicherzustellen, dass der Datensatz seit dem Lesen nicht geändert wurde. Im Allgemeinen wird dies durch Hinzufügen einer Version / etc-Spalte (INT / numerisch, die einen numerischen Wert enthält, der erhöht wird, wenn eine UPDATE-Anweisung erstellt wird) durchgeführt. IE:
Eine alternative Option ist die Verwendung eines Zeitstempels anstelle einer numerischen Spalte. Diese Spalte wird für keinen anderen Zweck verwendet als die Implementierung optimistischer Parallelität. Es kann eine Nummer oder ein Datum sein. Die Idee ist, dass es einen Wert erhält, wenn die Zeile eingefügt wird. Immer wenn der Datensatz gelesen wird, wird auch die Timestamp-Spalte gelesen. Wenn eine Aktualisierung durchgeführt wird, wird die Zeitstempelspalte überprüft. Wenn es zur UPDATE-Zeit denselben Wert hat wie beim Lesen, dann ist alles in Ordnung, das UPDATE wird ausgeführt und der Timestamp wird geändert! . Wenn der Zeitstempelwert zur UPDATE-Zeit unterschiedlich ist, wird ein Fehler an den Benutzer zurückgegeben - er muss den Datensatz erneut lesen, die Änderungen erneut vornehmen und versuchen, den Datensatz erneut zu aktualisieren.
Sie brauchen keine Transaktion, wenn Sie nur 1 Anweisung wie folgt verwenden:
%Vor%Tags und Links sql sql-server sql-server-2008 concurrency tsql