Optimistische Nebenläufigkeit

Optimistische Parallelität leitet ihren Namen von der optimistischen Annahme ab, dass Konflikte zwischen Transaktionen selten auftreten werden; Eine Kollision soll aufgetreten sein, wenn eine andere Transaktion eine Datenzeile zwischen dem Zeitpunkt, zu dem sie von der aktuellen Transaktion gelesen wird, und dem Zeitpunkt, zu dem sie aktualisiert oder gelöscht wird, aktualisiert oder gelöscht wird. Es ist das Gegenteil von pessimistischer Parallelität oder Sperrung, bei der der Anwendungsentwickler glaubt, dass solche Kollisionen an der Tagesordnung sind.

In optimistischer Parallelität bleibt eine Zeile entsperrt, bis sie aktualisiert oder gelöscht werden kann. An diesem Punkt wird die Zeile erneut gelesen und überprüft, ob sie seit dem letzten Lesen geändert wurde. Wenn sich die Zeile geändert hat, schlägt das Aktualisieren oder Löschen fehl und muss erneut versucht werden.

Um festzustellen, ob eine Zeile geändert wurde, wird die neue Version anhand einer zwischengespeicherten Version der Zeile überprüft. Diese Überprüfung kann auf der Zeilenversion basieren, z. B. der Zeitstempelspalte in SQL Server oder den Werten jeder Spalte in der Zeile. Viele DBMS unterstützen keine Zeilenversionen.

Optimistische Parallelität kann von der Datenquelle oder der Anwendung implementiert werden. In beiden Fällen sollte die Anwendung eine niedrige Transaktionsisolationsstufe verwenden, z. B. Read Committed; Die Verwendung einer höheren Ebene negiert die erhöhte Parallelität, die durch verwendung der optimistischen Parallelität erreicht wird.

Wenn die Datenquelle optimistische Parallelität implementiert, legt die Anwendung das Attribut der SQL_ATTR_CONCURRENCY-Anweisung auf SQL_CONCUR_ROWVER oder SQL_CONCUR_VALUES fest. Um eine Zeile zu aktualisieren oder zu löschen, führt sie eine positionierte Update- oder Delete-Anweisung aus oder ruft SQLSetPos wie bei pessimistischer Parallelität auf. Der Treiber oder die Datenquelle gibt SQLSTATE 01001 (Cursorvorgangskonflikt) zurück, wenn das Aktualisieren oder Löschen aufgrund einer Kollision fehlschlägt.

Wenn die Anwendung selbst optimistische Parallelität implementiert, legt sie das SQL_ATTR_CONCURRENCY-Anweisungsattribut auf SQL_CONCUR_READ_ONLY fest, um eine Zeile zu lesen. Wenn Zeilenversionen verglichen werden und die Zeilenversionsspalte nicht bekannt ist, wird SQLSpecialColumns mit der Option SQL_ROWVER aufgerufen, um den Namen dieser Spalte zu bestimmen.

Die Anwendung aktualisiert oder löscht die Zeile, indem sie die Parallelität auf SQL_CONCUR_LOCK erhöht (um Schreibzugriff auf die Zeile zu erhalten) und eine UPDATE - oder DELETE-Anweisung mit einer WHERE-Klausel ausführt, die die Version oder werte angibt, die die Zeile beim Lesen der Zeile hatte. Wenn sich die Zeile seitdem geändert hat, schlägt die Anweisung fehl. Wenn die WHERE-Klausel die Zeile nicht eindeutig identifiziert, kann die Anweisung auch andere Zeilen aktualisieren oder löschen. Zeilenversionen identifizieren Zeilen immer eindeutig, aber Zeilenwerte identifizieren Zeilen nur dann eindeutig, wenn sie den Primärschlüssel enthalten.