18.11.3 | Isolations-Ebenen |
Befindet sich die Datenbank-Sitzung nicht im Auto-Commit Modus, kann man durch das Setzen der Isolations-Ebene festlegen, inwiefern in einer Transaktion durchgeführte Änderungen für andere Clients sichtbar sind. Prinzipiell gilt, je restriktiver die Isolations-Ebene ist, desto schlechter wird die Performance beim Zugriff mehrerer Clients, da Sperren in der Datenbank gesetzt werden müssen.
Bei der Durchführung von Änderungen unterscheidet man prinzipiell folgende Probleme:Die einzelnen Isolations-Ebenen unterscheiden sich dadurch, dass sie jeweils verschiedene dieser möglichen Probleme beheben. Je mehr dieser Probleme in einer Transaktion behoben werden, desto geringer wird die Verarbeitungsgeschwindigkeit bei vielen gleichzeitigen Nutzerzugriffen, da für die größere Einschränkung der Sichtbarkeit von Änderungen in einer Transaktion mehr Sperren vom Datenbanksystem gesetzt werden müssen. In Abbildung 18.26 sind die in JDBC definierten Isolations-Ebenen aufgeführt (nach ANSI-92 SQL). Die in der ersten Spalte angegebenen Konstanten sind in der Klasse Connection definiert.
- Lesen nicht festgeschriebener Daten (»dirty read«).
Lesen von Datensätzen, die gerade in anderen Transaktionen geändert, aber noch nicht mit COMMIT festgeschrieben wurden. Wird ein Wert in Transaktion A geändert, danach von Transaktion B gelesen und anschließend wieder von Transaktion A durch ein ROLLBACK zurückgesetzt, hat Transaktion B einen ungültigen Wert geliefert.- Nicht wiederholtes Lesen (»non-repeatable read«).
Wiederholte Lesezugriffe auf dieselben Datensätze liefern innerhalb einer Transaktion unterschiedliche Werte. Angenommen, Transaktion A liest zunächst einen Datensatz, der danach von Transaktion B geändert und durch COMMIT festgeschrieben wird. Liest Transaktion A diesen Datensatz innerhalb derselben Transaktion erneut, liefern beide Lesevorgänge unterschiedliche Werte.- Phantom-Problem (»phantom read«).
Bei wiederholtem Durchführen von Abfragen innerhalb einer Transaktion werden neu eingefügte Datensätze sichtbar. Transaktion A führt eine Abfrage durch, die mehrere Datensätze zurückliefert und Transaktion B fügt eine neue Zeile ein, die auch in der Ergebnismenge der Abfrage von Transaktion A enthalten wäre. Wenn in Transaktion A die erste Abfrage ein zweites Mal ausgeführt wird, dann ist bei der zweiten Abfrage der von Transaktion B neu eingefügte Datensatz enthalten.
Nicht jedes Datenbanksystem unterstützt alle Isolations-Ebenen. Welche Isolations-Ebenen von einer Datenbank unterstützt werden, kann man über die Metadaten-Schnittstelle in JDBC ermitteln. Die Klasse DatabaseMetaData stellt hierfür die Methode supportsTransactionIsolationLevel() zur Verfügung. supportsTransactionIsolationLevel() erwartet als Parameter eine der in Abbildung 18.26 aufgeführten Konstanten. In den folgenden Zeilen wird geprüft, ob die Isolations-Ebene Serializable (nicht zu verwechseln mit dem Java-Interface Serializable) unterstützt wird:Connection con = DriverManager.getConnection(url, user, password); DatabaseMetaData meta = con.getMetaData(); if(meta.supportsTransactionIsolationLevel( Connection.TRANSACTION_SERIALIZABLE))) System.out.println("Serializable wird unterstützt"); else System.out.println("Serializable wird nicht unterstützt");
Die aktuelle Isolations-Ebene kann ebenfalls über die Metadaten-Schnittstelle mit der Methode getDefaultTransactionIsolation() ermittelt werden. Folgender Code-Ausschnitt zeigt, wie hierbei vorgegangen wird.Connection con = DriverManager.getConnection(url, user, password); DatabaseMetaData meta = con.getMetaData(); switch(meta.getDefaultTransactionIsolation()) { case Connection.TRANSACTION_NONE: System.out.println("none"); break; case Connection.TRANSACTION_READ_UNCOMMITTED: System.out.println("read uncommitted"); break; case Connection.TRANSACTION_READ_COMMITTED: System.out.println("read committed"); break; case Connection.TRANSACTION_REPEATABLE_READ: System.out.println("repeatable_read"); break; case Connection.TRANSACTION_SERIALIZABLE: System.out.println("serializable"); break; }