Warum ist optimistisches Sperren schneller als pessimistisches Sperren?

9

Beide Arten der Sperrung bewirken, dass ein Prozess auf eine korrekte Kopie des Datensatzes wartet, wenn dieser derzeit von einem anderen Prozess verwendet wird. Beim pessimistischen Sperren stammt der Sperrmechanismus aus der Datenbank selbst (einem nativen Sperrobjekt), während beim optimistischen Sperren der Sperrmechanismus eine Form der Zeilenversionierung wie ein Zeitstempel ist, um zu überprüfen, ob ein Datensatz "veraltet" ist oder nicht.

Aber beide bewirken, dass ein zweiter Prozess hängt. Ich frage also: Warum wird optimistisches Sperren im Allgemeinen als schneller / überlegen angesehen als pessimistisches Sperren? Und gibt es Anwendungsfälle, in denen Pessimismus Optimismus vorgezogen wird? Danke im Voraus!

Mara
quelle
5
Eine sehr kurze Erklärung findet sich in der Benennung. Optimistisches Sperren funktioniert gut, wenn die Wahrscheinlichkeit einer widersprüchlichen Sperre gering ist. Wir sind optimistisch hinsichtlich des Zusammenspiels mehrerer Prozesse. Pessimistisches Sperren funktioniert gut, wenn die Wahrscheinlichkeit eines widersprüchlichen Sperren hoch ist. Wir sind pessimistisch in Bezug auf das Zusammenspiel mehrerer Prozesse. Beide werden suboptimal abschneiden, wenn ihr Gegenteil angemessener wäre.
Mark Storey-Smith
Das optimistische Sperren kann je nach Arbeitsbelastung schneller sein als das pessimistische Sperren.
AK

Antworten:

8

Doppelte Frage von:

/programming/129329/optimistic-vs-pessimistic-locking

Antwort vom obigen Link kopieren / einfügen:

Optimistisches Sperren ist eine Strategie, bei der Sie einen Datensatz lesen, eine Versionsnummer notieren 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).

Bearbeiten (Hinzufügen weiterer Informationen zur Beantwortung der Leistungsfrage):

In Bezug auf die Leistung hängt es von Ihrer Umgebung ab. Berücksichtigen Sie die folgenden Faktoren, um zu entscheiden:

Sie werden feststellen, dass Optimismus aufgrund von Parallelität in den meisten Situationen besser ist. Abhängig vom RDBMS und der Umgebung kann dies jedoch weniger oder leistungsfähiger sein. In der Regel werden Sie beim Optimistic Locking feststellen, dass der Wert irgendwo zeilenversiert werden muss.

Bei MS SQL Server wird es beispielsweise in TempDB verschoben, und am Ende der Spalte werden zwischen 12 und 14 Byte angehängt. Das Aktivieren der optimistischen Sperrung mit einer Isolationsstufe wie Snapshot-Isolation kann zu einer Fragmentierung führen, und Ihr Füllfaktor muss angepasst werden, da die Zeilen jetzt zusätzliche Daten am Ende enthalten, die dazu führen können, dass eine Seite fast voll ist und sich die Seiten teilen deine Leistung. Wenn Ihre TempDB unteroptimiert ist, ist dies nicht so schnell.

Eine Checkliste lautet also:

  • - Haben Sie genügend E / A / Ressourcen, um die Form der Zeilenversionierung zu handhaben? Wenn nicht, fügen Sie Overhead hinzu. Wenn ja, wenn Sie die Daten häufig lesen, während Sie sie häufig für Schreibvorgänge sperren, werden Sie eine gute Verbesserung der Parallelität zwischen Lese- und Schreibvorgängen feststellen (obwohl Schreibvorgänge Schreibvorgänge weiterhin blockieren, Lesevorgänge Schreibvorgänge nicht mehr blockieren und umgekehrt).
  • - Ist Ihr Code anfällig für Deadlocks oder treten Sperren auf? Wenn Sie keine langen Sperren oder viele Deadlocks haben, würde der zusätzliche Aufwand für optimistisches Sperren die Dinge natürlich nicht schneller machen. In den meisten Fällen handelt es sich hier um Millisekunden.
  • -Wenn Ihre Datenbank groß ist (oder auf sehr begrenzter Hardware) und Ihre Datenseiten je nach RDBMS nahezu voll sind, können Sie große Seitensplits und Datenfragmentierungen verursachen. Denken Sie also daran, nach dem Einschalten eine Neuindizierung in Betracht zu ziehen.

Das sind meine Gedanken zu diesem Thema, offen dafür, mehr von der Community zu hören.

Ali Razeghi
quelle
Danke @Ali Razeghi (+1) - Ich denke, dba.se ist ein geeigneterer Ort für diese Frage. Auch wenn dies eine hervorragende Antwort ist, beantwortet sie nicht meine Frage nach der Leistung (wenn einer schneller als der andere ist). Danke noch einmal!
Mara
Hallo Mara, das ist ein guter Punkt. Ich habe die Antwort erweitert. Vielen Dank.
Ali Razeghi
11

Sie verstehen optimistisches Sperren falsch.

Optimistisches Sperren führt nicht dazu, dass Transaktionen aufeinander warten.

Optimistisches Sperren führt möglicherweise zum Fehlschlagen einer Transaktion, ohne dass jemals eine "Sperre" vorgenommen wurde. Und wenn eine Transaktion aufgrund einer optimistischen Sperrung fehlschlägt, muss der Benutzer erneut beginnen. Das Wort "optimistisch" leitet sich genau aus der Erwartung ab, dass die Bedingung, die dazu führt, dass Transaktionen aus diesem Grund fehlschlagen, nur sehr ausnahmsweise auftritt. "Optimistisches" Sperren ist der Ansatz, der besagt: "Ich werde keine tatsächlichen Sperren nehmen, weil ich hoffe, dass sie sowieso nicht benötigt werden. Wenn sich herausstellt, dass ich mich geirrt habe, werde ich den unvermeidlichen Fehler akzeptieren."

Erwin Smout
quelle
1

Optimistisches Sperren ist im Allgemeinen schneller, da es aus Datenbanksicht tatsächlich kein Sperren gibt. Es liegt ganz bei der Anwendung, ob die Versionsspalte (oder die Pseudospalte wie ora_rowscn) berücksichtigt wird oder nicht. Normalerweise sind viele Anwendungen mit derselben Datenbank verbunden, sodass db zu einer gemeinsam genutzten Ressource wird. Wenn diese hängt, sind alle Clients betroffen.

Bei einer optimistischen Sperrstrategie geschieht das Hängen auf der Clientseite und wirkt sich nicht auf andere aus.

Wenn ein Datensatz jedoch häufig aktualisiert wird, wird er möglicherweise zu oft erneut gelesen (im Falle einer optimistischen Sperrung), wodurch die meisten Vorteile einer optimistischen Strategie zunichte gemacht werden.

Ich würde der Überlegenheit beider Ansätze nicht zustimmen. beide können missbraucht werden. Pessimistisch ist fehleranfälliger, nur weil es gefährlicher ist: Das Sperren erfolgt auf DB-Ebene. Abhängig vom RDMS haben Sie möglicherweise keine Kontrolle darüber, was gesperrt ist (Sperreneskalation). Sie müssen sich manuell um die Sperrreihenfolge kümmern.

a1ex07
quelle
interessanter Punkt a1ex07, optimsitisches Sperren beinhaltet immer noch Sperren, da Schreibvorgänge immer andere Schreibvorgänge blockieren, richtig?
Ali Razeghi
Nein, tut es nicht. Deshalb ist es "schneller".
Erwin Smout
Dies könnte bei Oracle der Fall sein, bei MS SQL Server jedoch, da standardmäßig die Isolationsstufe "Lesefestgeschrieben" verwendet wird. Durch optimistisches Sperren können Lese- und Schreibthreads gleichzeitig arbeiten, Schreibvorgänge blockieren jedoch Schreibvorgänge, bis der blockierende Thread festgeschrieben wird.
Ali Razeghi
@Ali Razeghi: Ich bin nicht sicher, ob ich Ihrem Standpunkt folge. In SQLServer mit gelesenen festgeschriebenen Writern blockieren Leser standardmäßig die Leser, es sei denn, "READ_COMMITTED_SNAPSHOT" ist aktiviert. Optimistisches Sperren ist keine Sperre für die Datenbankressource (Zeile / Seite / Tabelle), sondern eine Vereinbarung zwischen allen Anwendungen, die die Datenbank verwenden, um den Datensatz nicht zu aktualisieren, wenn die Version nicht den Erwartungen entspricht.
a1ex07
1
@Eamon Nerbonne: Ich sagte über "Schriftsteller blockieren keine Leser" ... Wo haben Sie gesehen, dass ich etwas über "Schriftsteller blockieren / blockieren keine Schriftsteller" erwähnt habe?
a1ex07
0

Beim optimistischen Sperren wird davon ausgegangen, dass gleichzeitige Transaktionen abgeschlossen werden können, ohne sich gegenseitig zu beeinflussen. Optimistisches Sperren ist also schneller, da beim Ausführen von Transaktionen keine Sperren erzwungen werden. Es wird verhindert, dass Parallelitätsprobleme verursacht werden, die nicht geheilt werden können. Die Transaktion überprüft nur (drei Arten von Datensätzen, Zeitstempeldatentyp, alten und neuen Wert prüfen) die Daten, dass keine andere Transaktion die Daten geändert hat. Im Falle einer Änderung wird die Transaktion zurückgesetzt.

Bei der pessimistischen Sperrung wird davon ausgegangen, dass gleichzeitige Transaktionen miteinander in Konflikt stehen. Daher ist eine Sperrung erforderlich. Dies erfolgt durch Angabe der ISOLATION-Ebene (Read Uncommitted, Read Committed, Repeatable Read und Serializable) des Transaktionsmanagements. Durch Beheben der Sperre werden Parallelitätsprobleme behoben. Sperren dienen zum Schutz gemeinsam genutzter Ressourcen oder Objekte (Tabellen, Datenzeilen, Datenblöcke, zwischengespeicherte Elemente, Verbindungen und gesamte Systeme). Wir haben viele Arten von Sperren als gemeinsam genutzte Sperren, Aktualisierungssperren, Inset-Sperren, exklusive Sperren, Transaktionssperren, DML-Sperren, Schemasperren und Sicherungswiederherstellungssperren.

um mehr Ahnung zu bekommen

Premraj
quelle
-3

Es ist falsch zu sagen, dass pessimistisches Sperren langsamer als optimistisch ist oder dass optimistisch schneller ist. Eine klassische Abfrage, um diese unangemessene Denkweise zu demonstrieren, besteht darin, ein Aggregat für die verschiedenen RDBMS zu erstellen, wie z.

SELECT COUNT(*) FROM atable

Sie werden sehen, dass in dem RDBMS, das einen nativ optimistischen Ansatz unterstützt, die Zeit, die diese Abfrage benötigt, viel bedeutender ist als diejenigen, die eine nativ pessimistische Sperre haben

Auf meinem PC dauert dieselbe Abfrage beispielsweise 27 ms unter SQL Server und 109 ms nach PostGreSQL ...

Der zusätzliche Aufwand für das Lesen toter Versionen von MVCC-Zeilen und das Nichtzählen der Geisterdatensätze im Aggregat führt zu zusätzlichen Kosten, die der Pessimist nicht hat!

user7370003
quelle
4
Der Ansatz der DBMS-Parallelitätskontrolle ist orthogonal zum optimistischen / pessimistischen Sperren, und der Vergleich der Abfragelaufzeiten in zwei verschiedenen DBMS ist irreführend.
Mustaccio
Da SQL Server in der Lage ist, die beiden Sperrmodi auszuführen, können Sie dies leicht vergleichen, indem Sie in einem Benutzer-Parallelitätsansatz ein echtes Zeichen setzen.
user7370003