it-swarm.com.de

Optimistisches vs. pessimistisches Sperren

Ich verstehe die Unterschiede zwischen optimistischer und pessimistischer Einstellung. Könnte mir jetzt jemand erklären, wann ich einen der beiden generell verwenden würde?

Und ändert sich die Antwort auf diese Frage abhängig davon, ob ich eine gespeicherte Prozedur verwende, um die Abfrage auszuführen?

Optimistisch bedeutet jedoch "Tabelle beim Lesen nicht sperren" und pessimistisch "Tabelle beim Lesen sperren".

481
Jason Baker

Optimistic Locking ist eine Strategie, bei der Sie einen Datensatz lesen, eine Versionsnummer notieren (andere Methoden umfassen Datumsangaben, Zeitstempel oder Prüfsummen/Hashes) und prüfen, ob sich die Version vor Ihnen nicht geändert hat schreibe die Akte zurück. Wenn Sie den Datensatz zurückschreiben, filtern Sie das Update nach der Version, um sicherzustellen, dass es atomar ist. (d. h. wurde zwischen dem Überprüfen der Version und dem Schreiben des Datensatzes auf die Festplatte nicht aktualisiert) und Aktualisieren der Version mit einem Schlag.

Wenn der Datensatz verschmutzt ist (d. H. Eine andere Version als Ihre), brechen Sie die Transaktion ab und der Benutzer kann sie erneut 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 verwalten, da die Verbindungen aus einem Pool stammen und Sie möglicherweise nicht von einem Zugriff zum nächsten dieselbe Verbindung verwenden.

Pessimistic Locking 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 beim Anwendungsdesign vorsichtig vorgehen, um Deadlocks zu vermeiden. Um pessimistisches Sperren zu verwenden, benötigen Sie entweder eine direkte Verbindung zur Datenbank (wie dies normalerweise in 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 die Verbindung mit dieser ID wieder her. Das DBMS verwaltet die Sperren und ermöglicht es Ihnen, die Sitzung über die TxID zu sichern. So funktionieren verteilte Transaktionen mit Zwei-Phasen-Festschreibungsprotokollen (z. B. XA oder COM + -Transaktionen ).

Optimistisches Sperren wird verwendet, wenn Sie nicht mit vielen Kollisionen rechnen. Die Ausführung eines normalen Vorgangs kostet weniger, aber wenn die Kollision auftritt, zahlen Sie einen höheren Preis für die Lösung, 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.

148
Ilya Kochetov

Optimistic geht davon aus, dass sich beim Lesen nichts ändern wird.

Pessimistisch nimmt an, dass etwas wird und sperrt es so.

Wenn es nicht unbedingt erforderlich ist, dass die Daten perfekt gelesen werden, sollten Sie optimistisch sein. Es kann vorkommen, dass Sie das seltsame "schmutzige" Lesen bemerken - aber es ist weitaus unwahrscheinlicher, dass es zu Deadlocks und dergleichen kommt.

Die meisten Webanwendungen eignen sich gut für Dirty Reads - in den seltenen Fällen stimmen die Daten beim nächsten Neuladen nicht genau überein.

Verwenden Sie für genaue Datenoperationen (wie bei vielen Finanztransaktionen) Pessimistik. Es ist wichtig, dass die Daten genau und ohne nicht angezeigte Änderungen gelesen werden - der zusätzliche Sperraufwand lohnt sich.

Oh, und Microsoft SQL Server verwendet standardmäßig die Seitensperre - 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.

64
Keith

Zusätzlich zu dem, was bereits gesagt wurde, sollte gesagt werden, dass optimistisches Sperren dazu neigt, die Parallelität auf Kosten der Vorhersagbarkeit zu verbessern. Pessimistisches Sperren verringert in der Regel die Parallelität, ist jedoch vorhersehbarer.

Sie zahlen Ihr Geld usw

40
skaffman

Ich würde an einen weiteren Fall denken, in dem pessimistisches Sperren die bessere Wahl wäre.

Für ein optimistisches Sperren muss sich jeder Teilnehmer an einer Datenänderung damit einverstanden erklären, diese Art von Sperren zu verwenden. Wenn jedoch jemand die Daten ändert, ohne sich um die Versionsspalte zu kümmern, wird dies die gesamte Idee des optimistischen Sperrens zerstören.

17
Nikolay

Grundsätzlich gibt es zwei populärste Antworten. Das erste sagt im Grunde

Optimistic benötigt eine dreistufige Architektur, bei der Sie für Ihre Sitzung nicht unbedingt eine Verbindung zur Datenbank aufrechterhalten müssen. Bei der pessimistischen Sperrung wird der Datensatz für Ihre ausschließliche Verwendung gesperrt, bis Sie damit fertig sind. Es hat eine viel bessere Integrität als optimistisches Sperren. Sie benötigen entweder eine direkte Verbindung zur Datenbank.

Eine andere Antwort ist

optimistisch (Versionierung) ist schneller, weil keine Sperren vorhanden sind, aber (pessimistisch) Sperren funktionieren besser, wenn die Konflikte hoch sind und es besser ist, die Arbeit zu verhindern, als sie zu verwerfen und von vorne zu beginnen.

oder

Optimistisches Sperren funktioniert am besten, wenn Sie seltene Kollisionen haben

Wie es heißt auf dieser Seite.

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 in Ihrer Datenbank, sondern an die Dauer einer einzelnen Transaktion. Normalerweise öffnen Sie die Transaktion, führen eine Operation durch und schließen die Transaktion. Dies ist eine kurze, klassische Transaktion, die ANSI im Sinn hatte und die sich mit dem Sperren abfinden sollte. Aber wie implementieren Sie ein Ticketreservierungssystem, bei dem viele Kunden gleichzeitig dieselben Räume/Plätze reservieren?

Sie stöbern in den Angeboten, füllen das Formular mit vielen verfügbaren Optionen und aktuellen Preisen aus. Es dauert sehr lange und Optionen können überholt sein. Alle ungültigen Preise zwischen dem Ausfüllen des Formulars und dem Klicken auf die Schaltfläche "Ich stimme zu" sind ungültig, da die Daten, auf die Sie zugegriffen haben, nicht gesperrt wurden und jemand anderes, agilerer, eingegriffen hat Wenn Sie alle Preise ändern, müssen Sie einen Neustart mit neuen Preisen durchführen.

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 sinkt auf Null. Deshalb werden in der Realität optimistische Vorbehalte ausgenutzt. Wer zu lange trödelt, muss seine Reservierung zu höheren Preisen neu starten.

Bei diesem optimistischen Ansatz müssen Sie alle gelesenen Daten aufzeichnen (wie in mein wiederholtes Lesen ) und mit Ihrer Datenversion zum Festschreibungspunkt gelangen (ich möchte Aktien zum angezeigten Preis kaufen) in diesem Zitat nicht aktueller Preis). Zu diesem Zeitpunkt wird eine ANSI-Transaktion erstellt, die die Datenbank sperrt, überprüft, ob nichts geändert wurde, und Ihre Operation 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 eine neue Reservierung. Eine Transaktion beinhaltet hier menschliche Benutzerentscheidungen.

Ich bin weit davon entfernt, zu verstehen, wie man das MVCC manuell implementiert, aber ich denke, dass langfristige Transaktionen mit der Option eines Neustarts der Schlüssel zum Verständnis des Themas sind. Korrigiere mich, wenn ich irgendwo falsch liege. Meine Antwort war motiviert durch dieses Alex Kuznecov-Kapitel .

10
Little Alien

In den meisten Fällen ist optimistisches Sperren effizienter und bietet eine höhere Leistung. Beachten Sie bei der Auswahl zwischen pessimistischer und optimistischer Sperrung Folgendes:

  • Pessimistisches Sperren ist nützlich, wenn viele Aktualisierungen vorgenommen werden und die Wahrscheinlichkeit relativ hoch ist, dass Benutzer gleichzeitig versuchen, Daten zu aktualisieren. Wenn beispielsweise bei jedem Vorgang eine große Anzahl von Datensätzen gleichzeitig aktualisiert werden kann (die Bank fügt möglicherweise am Ende eines jeden Monats jedem Konto Zinserträge hinzu) und zwei Anwendungen gleichzeitig solche Vorgänge ausführen, treten Konflikte auf .

  • Pessimistisches Sperren ist auch in Anwendungen besser geeignet, 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 Vorgänge mit Lesezugriff.

9
Koenigsegg

Ein Anwendungsfall für optimistisches Sperren besteht darin, dass Ihre Anwendung die Datenbank verwendet, damit einer Ihrer Threads/Hosts eine Aufgabe beanspruchen kann. Diese Technik hat sich für mich regelmäßig bewährt.

Das beste Beispiel, das ich mir vorstellen kann, ist eine Task-Warteschlange, die mithilfe einer Datenbank implementiert wurde und in der mehrere Threads gleichzeitig Tasks anfordern. Wenn eine Aufgabe den Status 'Verfügbar', 'Beansprucht', 'Abgeschlossen' hat, kann eine Datenbankabfrage etwa "Status setzen = 'Beansprucht', wobei Status = 'Verfügbar' ist. 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, der nur optimistisches Sperren umfasst. Als Alternative zu der Aussage "Optimistisches Sperren wird verwendet, wenn Sie nicht mit vielen Kollisionen rechnen", kann sie auch verwendet werden, wenn Sie Kollisionen erwarten, aber genau eine Transaktion zum Erfolg führen möchten.

2
Charlie Camp