960 Stimmen

Optimistische vs. pessimistische Schließung

Ich verstehe die Unterschiede zwischen optimistischen und pessimistischen Schließungen. Könnte mir jetzt jemand erklären, wann ich eine von beiden generell verwenden würde?

Und ändert sich die Antwort auf diese Frage, je nachdem, ob ich eine gespeicherte Prozedur zur Ausführung der Abfrage verwende oder nicht?

Aber nur zur Kontrolle: Optimistisch bedeutet "die Tabelle beim Lesen nicht sperren" und pessimistisch bedeutet "die Tabelle beim Lesen sperren".

3 Stimmen

3 Stimmen

Das ist eine gute Frage, insbesondere weil in Serialisierbarkeit Ich lese At any technique type conflicts should be detected and considered, with similar overhead for both materialized and non-materialized conflicts .

4 Stimmen

Hier finden Sie eine gute Erklärung, hier auf SO, darüber, was die Grundlegendes Konzept der optimistischen Sperrung .

28voto

Little Alien Punkte 1

Im Grunde gibt es zwei gängige Antworten. Die erste sagt grundsätzlich

Optimistic benötigt eine dreistufige Architektur, bei der Sie nicht unbedingt eine Verbindung zur Datenbank für Ihre Sitzung aufrechterhalten müssen, während Pessimistic Locking bedeutet, dass Sie den Datensatz für Ihre ausschließliche Verwendung sperren, bis Sie ihn fertig bearbeitet haben. Es hat eine viel bessere Integrität als optimistisches Sperren Sie benötigen entweder eine direkte Verbindung zur Datenbank.

Eine andere Antwort lautet

optimistisch (Versionierung) ist schneller, weil es keine Sperren gibt, aber (pessimistische) Sperren sind besser, wenn es viele Konflikte gibt und es besser ist, die Arbeit zu verhindern, als sie zu verwerfen und neu zu beginnen.

oder

Optimistisches Sperren funktioniert am besten, wenn es seltene Kollisionen gibt.

Wie man es ausdrückt auf dieser Seite.

Ich habe meine Antwort verfasst, um zu erklären, wie "Verbindung halten" mit "wenig Kollisionen" zusammenhängt.

Um zu verstehen, welche Strategie für Sie am besten geeignet ist, denken Sie nicht an die Anzahl der Transaktionen pro Sekunde in Ihrer DB, sondern an die Dauer einer einzelnen Transaktion. Normalerweise öffnen Sie eine Transaktion, führen einen Vorgang aus und schließen die Transaktion. Dies ist eine kurze, klassische Transaktion, wie sie ANSI im Sinn hatte, und es ist in Ordnung, ohne Sperren auszukommen. Aber wie implementieren Sie ein Ticket-Reservierungssystem, bei dem viele Kunden gleichzeitig dieselben Räume/Sitzplätze reservieren?

Sie stöbern in den Angeboten und füllen das Formular mit vielen verfügbaren Optionen und aktuellen Preisen aus. Das nimmt viel Zeit in Anspruch, und die Optionen können veraltet sein, alle Preise sind ungültig, seit Sie mit dem Ausfüllen des Formulars begonnen und auf die Schaltfläche "Ich stimme zu" gedrückt haben, weil die Daten, auf die Sie zugegriffen haben, nicht gesperrt waren, und jemand anderes, der flinker ist, hat sich eingemischt und alle Preise geändert, und Sie müssen mit neuen Preisen neu beginnen.

Sie könnten stattdessen alle Optionen beim Lesen sperren. Das ist ein pessimistisches Szenario. Sie sehen, warum es scheiße ist. Ihr System kann von einem einzigen Clown zu Fall gebracht werden, der einfach eine Reservierung startet und dann raucht. Niemand kann etwas reservieren, bevor er fertig ist. Ihr Cashflow sinkt auf Null. Aus diesem Grund werden in der Realität optimistische Reservierungen vorgenommen. Diejenigen, die zu lange trödeln, müssen ihre Reservierung zu höheren Preisen neu starten.

Bei diesem optimistischen Ansatz müssen Sie alle Daten, die Sie lesen, aufzeichnen (wie in Mine Wiederholtes Lesen ) und kommen Sie zum Commit-Punkt mit Ihrer Version der Daten (ich möchte Aktien zu dem Preis kaufen, den Sie in diesem Angebot angezeigt haben, nicht zum aktuellen Preis). An diesem Punkt wird eine ANSI-Transaktion erstellt, die die DB sperrt, prüft, ob sich nichts geändert hat, und Ihre Operation festschreibt/abbricht. IMO ist dies eine effektive Emulation von MVCC die ebenfalls mit Optimistic CC verbunden ist und ebenfalls davon ausgeht, dass Ihre Transaktion im Falle eines Abbruchs neu beginnt, d. h. Sie nehmen eine neue Reservierung vor. Eine Transaktion beinhaltet hier eine menschliche Benutzerentscheidung.

Ich bin weit davon entfernt zu verstehen, wie man das MVCC manuell implementieren kann, aber ich denke, dass lang laufende Transaktionen mit der Möglichkeit des Neustarts der Schlüssel zum Verständnis des Themas sind. Korrigieren Sie mich, wenn ich irgendwo falsch liege. Meine Antwort wurde motiviert durch dieses Kapitel von Alex Kuznecov .

18voto

Koenigsegg Punkte 515

In den meisten Fällen ist das optimistische Sperren effizienter und bietet eine höhere Leistung. Bei der Wahl zwischen pessimistischem und optimistischem Sperren ist Folgendes zu beachten:

  • Pessimistisches Sperren ist nützlich, wenn es viele Aktualisierungen gibt und relativ hohe Wahrscheinlichkeit besteht, dass mehrere Benutzer gleichzeitig versuchen, Daten zu zur gleichen Zeit. Zum Beispiel, wenn jede Operation eine große Anzahl von Datensätze auf einmal aktualisieren kann (die Bank könnte am Ende eines jeden Monats Zinserträge auf jedes Konto am Ende eines jeden Monats), und zwei Anwendungen führen solche Vorgänge gleichzeitig ausführen, kommt es zu Konflikten.

  • Pessimistisches Sperren ist auch besser geeignet für Anwendungen, die kleine Tabellen enthalten, die häufig aktualisiert werden. Bei diesen so genannten Hotspots sind Konflikte so wahrscheinlich, dass optimistisches Sperren den Aufwand für das Zurückrollen konfliktbehafteter Transaktionen vergeudet.

  • Optimistisches Sperren ist sinnvoll, wenn die Wahrscheinlichkeit von Konflikten sehr hoch ist. gering ist - es gibt viele Datensätze, aber relativ wenige Benutzer, oder sehr wenige Aktualisierungen und hauptsächlich Lesevorgänge.

8voto

Charlie Camp Punkte 106

Ein Anwendungsfall für optimistisches Sperren ist, dass Ihre Anwendung die Datenbank verwendet, um einem Ihrer Threads/Hosts zu erlauben, eine Aufgabe zu "beanspruchen". Dies ist eine Technik, die sich für mich regelmäßig als nützlich erwiesen hat.

Das beste Beispiel, das mir einfällt, ist eine mit einer Datenbank implementierte Aufgabenwarteschlange mit mehreren Threads, die gleichzeitig Aufgaben anfordern. Wenn eine Aufgabe den Status 'Verfügbar', 'Beansprucht', 'Abgeschlossen' hat, kann eine Datenbankabfrage etwas sagen wie "Set status='Beansprucht' where status='Verfügbar'. Wenn mehrere Threads versuchen, den Status auf diese Weise zu ändern, scheitern alle bis auf den ersten Thread an den unsauberen Daten.

Beachten Sie, dass es sich hier um einen Anwendungsfall handelt, der nur optimistisches Sperren beinhaltet. Alternativ zu der Aussage "Optimistisches Sperren wird verwendet, wenn nicht viele Kollisionen zu erwarten sind", kann es auch verwendet werden, wenn Kollisionen zu erwarten sind, aber genau eine Transaktion erfolgreich sein soll.

7voto

Abhishek Shinde Punkte 71

Über optimistische und pessimistische Schließungen wurde bereits viel Gutes gesagt. Ein wichtiger Punkt, den es zu beachten gilt, ist der folgende:

Wenn wir optimistisches Sperren verwenden, müssen wir uns Gedanken darüber machen, wie sich die Anwendung von diesen Fehlern erholt.

Besonders in asynchronen, nachrichtengesteuerten Architekturen kann dies zu einer ungeordneten Nachrichtenverarbeitung oder zu verlorenen Aktualisierungen führen.

Fehlerszenarien müssen durchdacht werden.

3voto

Big Pumpkin Punkte 2772

In der Praxis bedeutet dies, dass bei der Aktualisierung eines verteilten Systems optimistisches Sperren in der DB unzureichend sein kann, um die erforderliche Konsistenz in allen Teilen des verteilten Systems zu gewährleisten.

Bei Anwendungen, die auf AWS aufgebaut sind, ist es zum Beispiel üblich, dass Daten sowohl in einer DB (z. B. DynamoDB) als auch in einem Speicher (z. B. S3) vorhanden sind. Wenn eine Aktualisierung sowohl DynamoDB als auch S3 berührt, kann eine optimistische Sperrung in DynamoDB dazu führen, dass die Daten in S3 inkonsistent bleiben. In solchen Fällen ist es wahrscheinlich sicherer, eine pessimistische Sperre zu verwenden, die in DynamoDB gehalten wird, bis die S3-Aktualisierung abgeschlossen ist. Tatsächlich bietet AWS eine Schließbibliothek zu diesem Zweck.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X