Optimistische Nebenläufigkeit
Optimistische Parallelität leitet ihren Namen von der optimistischen Annahme ab, dass Konflikte zwischen Transaktionen selten auftreten. Es wird angenommen, dass eine Kollision aufgetreten ist, wenn eine andere Transaktion aktualisiert oder eine Datenzeile zwischen dem Zeitpunkt, zu dem sie von der aktuellen Transaktion gelesen wird, und der Zeitpunkt, zu dem sie aktualisiert oder gelöscht wird, gelöscht wird. Es ist das Gegenteil von pessimistischer Parallelität oder Sperrung, in der der Anwendungsentwickler glaubt, dass solche Kollisionen üblich sind.
In optimistischer Parallelität bleibt eine Zeile entsperrt, bis die Zeit zum Aktualisieren oder Löschen erfolgt. An diesem Punkt wird die Zeile erneut gelesen und überprüft, um festzustellen, ob sie seit dem letzten Lesen geändert wurde. Wenn sich die Zeile geändert hat, schlägt die Aktualisierung oder löschung 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 DBMSs 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. "Zugesichert lesen"; Die Verwendung einer höheren Ebene negiert die erhöhte Parallelität, die durch optimistische Parallelität gewonnen wurde.
Wenn optimistische Parallelität von der Datenquelle implementiert wird, legt die Anwendung das attribut der SQL_ATTR_CONCURRENCY-Anweisung auf SQL_CONCUR_ROWVER oder SQL_CONCUR_VALUES fest. Zum Aktualisieren oder Löschen einer Zeile führt sie eine positionierte Aktualisierungs- oder Löschanweisung aus oder ruft SQLSetPos genauso wie bei pessimistischer Parallelität auf. Der Treiber oder die Datenquelle gibt SQLSTATE 01001 (Cursorvorgangskonflikt) zurück, wenn die Aktualisierung oder Löschung aufgrund einer Kollision fehlschlägt.
Wenn die Anwendung selbst optimistische Parallelität implementiert, wird das attribut der SQL_ATTR_CONCURRENCY-Anweisung auf SQL_CONCUR_READ_ONLY festgelegt, um eine Zeile zu lesen. Wenn Sie Zeilenversionen vergleichen und die Zeilenversionsspalte nicht kennen, ruft sie SQLSpecialColumns mit der Option SQL_ROWVER auf, um den Namen dieser Spalte zu bestimmen.
Die Anwendung aktualisiert oder löscht die Zeile, indem die Parallelität auf SQL_CONCUR_LOCK erhöht wird (um Schreibzugriff auf die Zeile zu erhalten) und eine UPDATE- oder DELETE-Anweisung mit einer WHERE-Klausel auszuführen, die die Version oder Werte angibt, die die Zeile beim Lesen der Anwendung 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 Zeilen, aber Zeilenwerte identifizieren zeilen nur dann eindeutig, wenn sie den Primärschlüssel enthalten.