Ich verstehe die Unterschiede zwischen optimistischem und pessimistischem Locking. Könnte mir jetzt jemand erklären, wann ich eines von beiden generell verwenden würde?
Und ändert sich die Antwort auf diese Frage abhängig davon, ob ich eine gespeicherte Prozedur zum Ausführen der Abfrage verwende oder nicht?
Aber nur um zu überprüfen, bedeutet optimistisch "sperren Sie die Tabelle nicht beim Lesen" und pessimistisch bedeutet "sperren Sie die Tabelle beim Lesen".
sql-server
locking
optimistic-locking
pessimistic-locking
Jason Baker
quelle
quelle
At any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts
.Antworten:
Optimistisches Sperren ist eine Strategie, bei der Sie einen Datensatz lesen, eine Versionsnummer notieren (andere Methoden hierfür sind Datumsangaben, Zeitstempel oder Prüfsummen / Hashes) und überprüfen, ob sich die Version nicht geändert hat, bevor Sie den Datensatz zurückschreiben. Wenn Sie den Datensatz zurückschreiben, filtern Sie das Update nach der Version, um sicherzustellen, dass es atomar ist. (dh wurde nicht aktualisiert, wenn Sie die Version überprüfen und den Datensatz auf die Festplatte schreiben) und aktualisieren Sie die Version mit einem Schlag.
Wenn der Datensatz verschmutzt ist (dh eine andere Version als Ihre), brechen Sie die Transaktion ab und der Benutzer kann sie neu starten.
Diese Strategie eignet sich am besten für Systeme mit hohem Volumen und dreistufige Architekturen, bei denen Sie für Ihre Sitzung nicht unbedingt eine Verbindung zur Datenbank aufrechterhalten müssen. In dieser Situation kann der Client keine Datenbanksperren aufrechterhalten, da die Verbindungen aus einem Pool entnommen werden und Sie möglicherweise nicht dieselbe Verbindung von einem Zugriff zum nächsten verwenden.
Pessimistisches Sperren ist, wenn Sie den Datensatz für Ihre ausschließliche Verwendung sperren, bis Sie damit fertig sind. Es hat eine viel bessere Integrität als optimistisches Sperren, erfordert jedoch, dass Sie mit Ihrem Anwendungsdesign vorsichtig sind, um Deadlocks zu vermeiden . Um pessimistisches Sperren zu verwenden, benötigen Sie entweder eine direkte Verbindung zur Datenbank (wie dies normalerweise bei einer zweistufigen Client-Server- Anwendung der Fall ist ) oder eine extern verfügbare Transaktions-ID, die unabhängig von der Verbindung verwendet werden kann.
Im letzteren Fall öffnen Sie die Transaktion mit der TxID und stellen dann mit dieser ID die Verbindung wieder her. Das DBMS verwaltet die Sperren und ermöglicht es Ihnen, die Sitzung über die TxID wieder aufzunehmen. So funktionieren verteilte Transaktionen mit zweiphasigen Festschreibungsprotokollen (z. B. XA- oder COM + -Transaktionen ).
quelle
Optimistisches Sperren wird verwendet, wenn Sie nicht viele Kollisionen erwarten. Die Durchführung eines normalen Vorgangs kostet weniger, aber wenn die Kollision auftritt, zahlen Sie einen höheren Preis, um sie zu beheben, da die Transaktion abgebrochen wird.
Pessimistisches Sperren wird verwendet, wenn eine Kollision erwartet wird. Die Transaktionen, die die Synchronisation verletzen würden, werden einfach blockiert.
Um den richtigen Sperrmechanismus auszuwählen, müssen Sie die Anzahl der Lese- und Schreibvorgänge schätzen und entsprechend planen.
quelle
Optimistic geht davon aus, dass sich beim Lesen nichts ändern wird.
Pessimistisch geht davon aus, dass etwas wird und sperrt es so.
Wenn es nicht unbedingt erforderlich ist, dass die Daten perfekt gelesen werden, verwenden Sie optimistisch. Möglicherweise wird das eine oder andere "schmutzig" gelesen - aber es ist weitaus weniger wahrscheinlich, dass es zu Deadlocks und Ähnlichem kommt.
Die meisten Webanwendungen sind mit Dirty Reads in Ordnung - in seltenen Fällen stimmen die Daten beim nächsten Neuladen nicht genau überein.
Verwenden Sie für genaue Datenoperationen (wie bei vielen Finanztransaktionen) pessimistisch. Es ist wichtig, dass die Daten ohne nicht angezeigte Änderungen genau gelesen werden - der zusätzliche Sperraufwand lohnt sich.
Oh, und Microsoft SQL Server verwendet standardmäßig das Sperren von Seiten - im Grunde die Zeile, die Sie lesen, und einige auf beiden Seiten. Das Sperren von Zeilen ist genauer, aber viel langsamer. Es lohnt sich oft, Ihre Transaktionen auf "Read Commit" oder "No Lock" zu setzen, um Deadlocks beim Lesen zu vermeiden.
quelle
Zusätzlich zu dem, was bereits gesagt wurde:
optimistic
Sperren dazu neigt, die Parallelität auf Kosten der Vorhersagbarkeit zu verbessern.Pessimistic
Das Sperren verringert tendenziell die Parallelität, ist jedoch vorhersehbarer. Sie bezahlen Ihr Geld usw.quelle
Im Umgang mit Konflikten haben Sie zwei Möglichkeiten:
Betrachten wir nun die folgende Lost Update-Anomalie :
Die Anomalie "Lost Update" kann in der Isolationsstufe " Read Committed" auftreten .
In der Abbildung oben sehen wir, dass Alice glaubt, 40 von ihr abheben zu können,
account
aber nicht merkt, dass Bob gerade den Kontostand geändert hat, und jetzt sind nur noch 20 auf diesem Konto.Pessimistisches Sperren
Pessimistisches Sperren erreicht dieses Ziel, indem das Konto gemeinsam genutzt oder gelesen wird, sodass Bob das Konto nicht ändern kann.
In der obigen Abbildung erhalten Alice und Bob eine Lesesperre für die
account
Tabellenzeile, die beide Benutzer gelesen haben. Die Datenbank erwirbt diese Sperren auf SQL Server, wenn Repeatable Read oder Serializable verwendet wird.Da sowohl Alice als auch Bob das
account
mit dem PK-Wert von gelesen haben1
, kann keiner von ihnen es ändern, bis ein Benutzer die Lesesperre aufhebt. Dies liegt daran, dass eine Schreiboperation eine Schreib- / Exklusivsperre erfordert und gemeinsam genutzte / Lesesperren Schreib- / Exklusivsperren verhindern.Erst nachdem Alice ihre Transaktion festgeschrieben hat und die Lesesperre für die
account
Zeile aufgehoben wurde, wird BobUPDATE
die Änderung fortsetzen und anwenden. Bis Alice die Lesesperre aufhebt, blockiert Bobs UPDATE.Optimistisches Sperren
Durch optimistisches Sperren kann der Konflikt auftreten, wird jedoch beim Anwenden von Alices UPDATE erkannt, wenn sich die Version geändert hat.
Dieses Mal haben wir eine zusätzliche
version
Spalte. Dieversion
Spalte wird jedes Mal inkrementiert, wenn ein UPDATE oder DELETE ausgeführt wird, und sie wird auch in der WHERE-Klausel der UPDATE- und DELETE-Anweisungen verwendet. Damit dies funktioniert, müssen wir SELECT ausgeben und den aktuellenversion
Wert lesen, bevor wir UPDATE oder DELETE ausführen. Andernfalls wissen wir nicht, welchen Versionswert an die WHERE-Klausel übergeben oder inkrementiert werden soll.Transaktionen auf Anwendungsebene
Relationale Datenbanksysteme sind in den späten 70er und frühen 80er Jahren entstanden, als ein Client normalerweise über ein Terminal eine Verbindung zu einem Mainframe herstellte. Aus diesem Grund definieren Datenbanksysteme immer noch Begriffe wie die SESSION-Einstellung.
Heutzutage führen wir über das Internet keine Lese- und Schreibvorgänge mehr im Kontext derselben Datenbanktransaktion aus, und ACID reicht nicht mehr aus.
Betrachten Sie beispielsweise den folgenden Anwendungsfall:
Ohne optimistisches Sperren wäre dieses verlorene Update auf keinen Fall abgefangen worden, selbst wenn die Datenbanktransaktionen Serializable verwendet hätten. Dies liegt daran, dass Lese- und Schreibvorgänge in separaten HTTP-Anforderungen ausgeführt werden, daher bei verschiedenen Datenbanktransaktionen.
Optimistisches Sperren kann Ihnen also helfen, verlorene Updates zu verhindern, selbst wenn Sie Transaktionen auf Anwendungsebene verwenden, die auch die Denkzeit des Benutzers berücksichtigen.
Fazit
Optimistisches Sperren ist eine sehr nützliche Technik und funktioniert auch dann einwandfrei, wenn weniger strenge Isolationsstufen wie Read Committed verwendet werden oder wenn Lese- und Schreibvorgänge in nachfolgenden Datenbanktransaktionen ausgeführt werden.
Der Nachteil der optimistischen Sperrung besteht darin, dass das Datenzugriffsframework beim Abfangen eines Rollbacks ein Rollback auslöst
OptimisticLockException
und somit die gesamte Arbeit verliert, die wir zuvor durch die aktuell ausgeführte Transaktion geleistet haben.Je mehr Streit, desto mehr Konflikte und desto größer die Chance, Transaktionen abzubrechen. Rollbacks können für das Datenbanksystem kostspielig sein, da alle derzeit ausstehenden Änderungen rückgängig gemacht werden müssen, die sowohl Tabellenzeilen als auch Indexdatensätze betreffen können.
Aus diesem Grund kann pessimistisches Sperren bei häufigen Konflikten geeignet sein, da es die Wahrscheinlichkeit verringert, dass Transaktionen zurückgesetzt werden.
quelle
PESSIMISTIC_FORCE_INCREMENT
.Ich würde mir einen weiteren Fall vorstellen, in dem pessimistisches Sperren die bessere Wahl wäre.
Für ein optimistisches Sperren muss jeder Teilnehmer an Datenänderungen der Verwendung dieser Art des Sperren zustimmen. Wenn jedoch jemand die Daten ändert, ohne sich um die Versionsspalte zu kümmern, wird dies die gesamte Idee der optimistischen Sperrung zerstören.
quelle
Grundsätzlich gibt es zwei beliebteste Antworten. Der erste sagt im Grunde
Eine andere Antwort ist
oder
Wie es auf dieser Seite steht.
Ich habe meine Antwort erstellt, um zu erklären, wie "Verbindung halten" mit "geringen Kollisionen" zusammenhängt.
Um zu verstehen, welche Strategie für Sie am besten geeignet ist, denken Sie nicht an die Transaktionen pro Sekunde, die Ihre Datenbank hat, sondern an die Dauer einer einzelnen Transaktion. Normalerweise öffnen Sie die Transaktion, führen eine Operation aus und schließen die Transaktion. Dies ist eine kurze, klassische Transaktion, die ANSI im Sinn hatte und die gut für das Sperren geeignet ist. Aber wie implementieren Sie ein Ticketreservierungssystem, bei dem viele Kunden gleichzeitig dieselben Zimmer / Plätze reservieren?
Sie durchsuchen die Angebote, füllen das Formular mit vielen verfügbaren Optionen und aktuellen Preisen aus. Es dauert sehr lange und die Optionen können veraltet sein. Alle Preise, die zwischen dem Ausfüllen des Formulars und dem Drücken der Schaltfläche "Ich stimme zu" ungültig sind, wurden nicht gesperrt, da die Daten, auf die Sie zugegriffen haben, nicht gesperrt waren und jemand anderes, agiler, eingegriffen hat Wenn Sie alle Preise ändern, müssen Sie mit neuen Preisen neu starten.
Sie können stattdessen alle Optionen beim Lesen sperren. Dies ist ein pessimistisches Szenario. Sie sehen, warum es scheiße ist. Ihr System kann von einem einzelnen Clown heruntergefahren werden, der einfach eine Reservierung startet und raucht. Niemand kann etwas reservieren, bevor er fertig ist. Ihr Cashflow fällt auf Null. Deshalb werden in der Realität optimistische Vorbehalte verwendet. Wer zu lange trödelt, muss seine Reservierung zu höheren Preisen neu starten.
Bei diesem optimistischen Ansatz müssen Sie alle Daten, die Sie gelesen haben (wie in meinem wiederholten Lesen ) , aufzeichnen und mit Ihrer Datenversion zum Festschreibungspunkt gelangen (ich möchte Aktien zu dem Preis kaufen, den Sie in diesem Angebot angegeben haben, nicht zum aktuellen Preis ). Zu diesem Zeitpunkt wird eine ANSI-Transaktion erstellt, die die Datenbank sperrt, prüft, ob nichts geändert wurde, und Ihren Vorgang festschreibt / abbricht. IMO, dies ist eine effektive Emulation von MVCC , die auch mit Optimistic CC verbunden ist und davon ausgeht, dass Ihre Transaktion im Falle eines Abbruchs neu gestartet wird, dh Sie werden eine neue Reservierung vornehmen. Eine Transaktion beinhaltet hier menschliche Benutzerentscheidungen.
Ich bin weit davon entfernt zu verstehen, wie das MVCC manuell implementiert wird, aber ich denke, dass lang laufende Transaktionen mit der Option eines Neustarts der Schlüssel zum Verständnis des Themas sind. Korrigieren Sie mich, wenn ich irgendwo falsch liege. Meine Antwort wurde durch dieses Kapitel von Alex Kuznecov motiviert .
quelle
In den meisten Fällen ist eine optimistische Verriegelung effizienter und bietet eine höhere Leistung. Beachten Sie bei der Auswahl zwischen pessimistischem und optimistischem Sperren Folgendes:
Pessimistisches Sperren ist nützlich, wenn viele Aktualisierungen und eine relativ hohe Wahrscheinlichkeit bestehen, dass Benutzer versuchen, Daten gleichzeitig zu aktualisieren. Wenn beispielsweise jeder Vorgang eine große Anzahl von Datensätzen gleichzeitig aktualisieren kann (die Bank kann am Ende eines jeden Monats jedem Konto Zinserträge hinzufügen) und zwei Anwendungen solche Vorgänge gleichzeitig ausführen, treten Konflikte auf .
Pessimistisches Sperren eignet sich auch besser für Anwendungen, die kleine Tabellen enthalten, die häufig aktualisiert werden. Bei diesen sogenannten Hotspots sind Konflikte so wahrscheinlich, dass ein optimistisches Sperren den Aufwand für das Zurücksetzen widersprüchlicher Transaktionen verschwendet.
Optimistisches Sperren ist nützlich, wenn die Wahrscheinlichkeit von Konflikten sehr gering ist - es gibt viele Datensätze, aber relativ wenige Benutzer oder nur sehr wenige Aktualisierungen und meistens Lesevorgänge.
quelle
Ein Anwendungsfall für optimistisches Sperren besteht darin, dass Ihre Anwendung die Datenbank verwendet, damit einer Ihrer Threads / Hosts eine Aufgabe "beanspruchen" kann. Dies ist eine Technik, die sich für mich regelmäßig als nützlich erwiesen hat.
Das beste Beispiel, das ich mir vorstellen kann, ist eine Aufgabenwarteschlange, die mithilfe einer Datenbank implementiert wird, wobei mehrere Threads gleichzeitig Aufgaben beanspruchen. Wenn eine Aufgabe den Status "Verfügbar", "Beansprucht", "Abgeschlossen" hat, kann eine Datenbankabfrage beispielsweise "Status festlegen =" Beansprucht ", wobei status =" Verfügbar "lautet. Wenn mehrere Threads versuchen, den Status auf diese Weise zu ändern, Alle bis auf den ersten Thread schlagen aufgrund fehlerhafter Daten fehl.
Beachten Sie, dass dies ein Anwendungsfall ist, bei dem nur optimistisch gesperrt wird. Als Alternative zu "Optimistisches Sperren wird verwendet, wenn Sie nicht viele Kollisionen erwarten" kann es auch verwendet werden, wenn Sie Kollisionen erwarten, aber genau eine Transaktion erfolgreich sein möchten.
quelle
Über das optimistische und pessimistische Sperren wurden oben viele gute Dinge gesagt. Ein wichtiger zu berücksichtigender Punkt ist folgender:
Wenn Sie optimistisches Sperren verwenden, müssen Sie darauf achten, wie sich die Anwendung von diesen Fehlern erholt.
Insbesondere in asynchronen nachrichtengesteuerten Architekturen kann dies zu einer fehlerhaften Nachrichtenverarbeitung oder zu verlorenen Aktualisierungen führen.
Fehlerszenarien müssen durchdacht werden.
quelle