Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Anywhere Server - SQL-Benutzerhandbuch » Datenbanken erstellen » Transaktionen und Isolationsstufen verwenden » Funktionsweise von Sperren

 

Sperren bei Abfragen

Welche Sperren SQL Anywhere verwendet, wenn ein Benutzer eine SELECT-Anweisung eingibt, hängt von der Isolationsstufe der Transaktion ab. Unabhängig von der Isolationsstufe setzen alle SELECT-Anweisungen Schemasperren für die referenzierten Tabellen.

SELECT-Anweisungen auf Isolationsstufe 0

Bei einer SELECT-Anweisung auf Isolationsstufe 0 sind keine Sperren erforderlich. Die Transaktionen sind nicht vor Änderungen durch andere Transaktionen geschützt. Der Programmierer oder Datenbankbenutzer muss die Ergebnisse dieser Abfragen richtig interpretieren und sich der Flüchtigkeit der abgerufenen Informationen bewusst sein.

SELECT-Anweisungen auf Isolationsstufe 1

SQL Anywhere verwendet, wenn eine Transaktion auf Isolationsstufe 1 ausgeführt wird, nicht viel mehr Sperren als auf Isolationsstufe 0. Der Datenbankserver ändert sein Verhalten nur auf zwei Arten.

Der erste Unterschied hat nichts mit dem Setzen von Sperren zu tun, sondern vielmehr mit deren Respektierung. Auf Isolationsstufe 0 kann eine Transaktion jede Zeile lesen, sogar wenn eine andere Transaktion eine Schreibsperre gesetzt hat. Im Unterschied dazu muss jede Transaktion mit der Isolationsstufe 1 vor dem Lesen einer Zeile überprüfen, ob es dafür eine Schreibsperre gibt. Sie kann nicht über schreibgesperrte Zeilen hinaus lesen, da dies bedeuten könnte, nicht festgeschriebene Daten zu lesen. Die Verwendung des Hints READPAST erlaubt es dem Server, mit Schreibsperren versehene Zeilen zu ignorieren, aber während die Transaktion nicht mehr blockiert, stimmt ihre Semantik nicht mehr mit derjenigen der Isolationsstufe 1 überein. Einzelheiten dazu finden Sie in den Erläuterungen zum Hint READPAST unter FROM-Klausel.

Der zweite Unterschied betrifft die Cursorstabilität. Cursorstabilität wird durch das Setzen einer kurzfristigen Lesesperre für die aktuelle Zeile des Cursors erzielt. Diese Lesesperre wird freigegeben, wenn sich der Cursor verschiebt. Es kann mehr als eine Zeile davon betroffen sein, wenn der Inhalt des Cursors das Ergebnis einer Verbindung ist. In diesem Fall setzt der Datenbankserver kurzfristige Lesesperren für alle Zeilen, die Informationen zur aktuellen Zeile des Cursor beigetragen haben, und gibt diese Sperren frei, wenn eine andere Zeile des Cursor als aktuelle Zeile ausgewählt wurde.

SELECT-Anweisungen auf Isolationsstufe 2

Auf Isolationsstufe 2 ändert der Datenbankserver seine Prozeduren, um die Semantik wiederholbarer Lesevorgänge zu gewährleisten. Wenn eine SELECT-Anweisung Werte aus jeder Zeile einer Tabelle liefert, setzt der Datenbankserver eine Lesesperre für jede Zeile der Tabelle, sobald er sie liest. Enthält aber die SELECT-Anweisung eine WHERE-Klausel oder eine andere Bedingung, die die Zeilen im Ergebnis einschränkt, dann liest der Datenbankserver stattdessen jede Zeile, vergleicht die Werte in der Zeile mit der Bedingung und setzt eine Lesesperre für die Zeile, wenn sie die Bedingung erfüllt. Die gesetzten Lesesperren sind langfristige Lesesperren und werden aufrecht erhalten, bis die Transaktion durch eine implizite oder explizite COMMIT- oder ROLLBACK-Anweisung abgeschlossen wird. Wie bei Isolationsstufe 1 wird die Cursorstabilität auch auf Isolationsstufe 2 gewährleistet und Dirty Reads sind nicht erlaubt.

SELECT-Anweisungen auf Isolationsstufe 3

Bei Transaktionen auf Isolationsstufe 3 muss der Datenbankserver gewährleisten, dass alle Transaktionspläne serialisierbar sind. Besonders müssen, zusätzlich zu den Anforderungen der Isolationsstufe 2, Phantomzeilen verhindert werden, sodass die erneute Ausführung der gleichen Anweisung unter allen Umständen garantiert die gleichen Ergebnisse liefert.

Um diese Anforderung zu erfüllen, verwendet der Datenbankserver Lese- und Phantomsperren. Wenn eine SELECT-Anweisung auf Isolationsstufe 3 ausgeführt wird, setzt der Datenbankserver eine Lesesperre für jede Zeile, die während der Berechnung der Ergebnismenge verarbeitet wird. Dadurch wird gewährleistet, dass keine anderen Transaktionen diese Zeilen ändern können, bevor die Transaktion abgeschlossen ist.

Diese Anforderung ähnelt den Vorgängen, die der Datenbankserver auf Isolationsstufe 2 durchführt. Der Unterschied besteht jedoch darin, dass eine Sperre für jede gelesene Zeile gesetzt werden muss, egal ob diese Zeilen die Prädikate in den Klauseln WHERE, ON oder HAVING von SELECT erfüllen. Wenn Sie zum Beispiel die Namen aller Angestellten in der Verkaufsabteilung auswählen, muss der Server alle Zeilen mit Informationen über Verkaufspersonal sperren, egal ob die Transaktion auf Isolationsstufe 2 oder 3 ausgeführt wird. Auf Isolationsstufe 3 muss der Server aber auch Lesesperren für jede Zeile mit Angestellten gesetzt werden, die nicht in der Verkaufsabteilung arbeiten. Andernfalls könnte eine andere Transaktion möglicherweise einen anderen Angestellten in die Verkaufsabteilung transferieren, während die erste Transaktion noch ausgeführt wird.

Es gibt zwei Auswirkungen, wenn eine Lesesperre für jeden Zeilenlesevorgang gesetzt werden muss:

  • Der Datenbankserver muss möglicherweise mehr Sperren setzen, als auf Isolationsstufe 2 notwendig wären. Die Anzahl der gesetzten Phantomsperren ist größer als die Anzahl der Lesesperren, die für den Scan gesetzt werden. Diese Verdoppelung des Sperren-Overheads verlängert die Ausführungszeit der Anforderung.

  • Das Setzen von Lesesperren für jede gelesene Zeile hat negative Auswirkungen auf die Parallelität der Aktualisierungsvorgänge für die Tabelle in der Datenbank.

Die Anzahl der vom Datenbankserver gesetzten Phantomsperren kann stark schwanken und hängt von der Ausführungsstrategie ab, die vom Abfrageoptimierer gewählt wurde. Der SQL Anywhere-Abfrageoptimierer versucht, sequenzielle Scans auf Isolationsstufe 3 zu vermeiden, da sich diese nachteilig auf die Parallelität des Gesamtsystems auswirken können. Die Fähigkeit des Optimierers zur Vermeidung hängt jedoch von den Prädikaten in der Anweisung und von den relevanten Indizes ab, die in den referenzierten Tabellen verfügbar sind.

Nehmen wir zum Beispiel an, Sie wollen Informationen über den Mitarbeiter mit der Mitarbeiter-ID 123 auswählen. Da EmployeeID der Primärschlüssel der Employees-Tabelle ist, wird der Abfrageoptimierer mit großer Wahrscheinlichkeit eine index-basierte Strategie unter Verwendung des Primärschlüsselindexes wählen, um die Zeile auf effiziente Weise zu finden. Außerdem besteht keine Gefahr, dass eine andere Transaktion die Kennung eines anderen Angestellten auf 123 ändern könnte, da Primärschlüsselwerte eindeutig sein müssen. Der Server kann garantieren, dass kein zweiter Angestellter die gleiche Kennung hat, indem eine Lesesperre für die Zeile gestzt wird, die die Information über den Angestellten mit der Kennung 123 enthält.

Im Gegensatz dazu müsste der Datenbankserver eine größere Anzahl von Sperren setzen, würde er alle Angestellten in der Verkaufsabteilung auswählen. Da es keinen relevanten Index gibt, muss der Datenbankserver jede Zeile in der Mitarbeitertabelle lesen und für jeden Mitarbeiter prüfen, ob er zur Verkaufsabteilung gehört. Wenn dies der Fall ist, müssen sowohl Lese- als auch Phantomsperren für jede Zeile in der Tabelle gesetzt werden.

SELECT-Anweisungen und Snapshot-Isolation

SELECT-Anweisungen, die mit den Isolationsstufen snapshot, statement-snapshot oder readonly-statement-snapshot ausgeführt werden, setzen keine Lesesperren. Der Grund dafür ist, dass jede Snapshot-Transaktion (oder -Anweisung) einen Snapshot eines festgeschriebenen Zustands zu einem Zeitpunkt in der Vergangenheit berücksichtigt. Der jeweilige Zeitpunkt hängt davon ab, welche der drei Snapshot-Isolationsstufen von der Anweisung benutzt werden. Lesetransaktionen blockieren niemals Aktualisierungstransaktionen, und Aktualisierungstransaktionen blockieren keine Lesevorgänge. Daher kann die Snapshot-Isolation beträchtliche Vorteile im Hinblick auf die Parallelität bieten, zusätzlich zu den offensichtlichen Konsistenzvorteilen. Es gibt jedoch einen Nachteil: Die Snapshot-Isolation kann sehr kostspielig sein. Dies liegt daran, dass wegen der Konsistenzgarantie der Snapshot-Isolation Kopien von geänderten Zeilen für andere Transaktionen gespeichert, verfolgt und schließlich gelöscht werden müssen.