http://www.postgresql-support.de

Transaction Isolation Level und Transactions

In diesem Abschnitt wollen wir uns ansehen, wie Transaktionen gesteuert werden können. Der JDBC Standard stellt einige Möglichkeiten bereit, die jedoch noch nicht alle restlos implementiert sind. Es ist davon auszugehen, dass zukünftige Versionen des PostgreSQL JDBC-Treibers hier bereits mehr Funktionalitäten bereitstellen.

Der folgende Code zeigt, wie eine einfache Transaktion abgearbeitet werden kann:

import java.sql.*;
import org.postgresql.jdbc3.*;

public class MakeConnection
{
        Statement       stmt;

        public static void main(String[] args)
        {
                MakeConnection conn = new MakeConnection();
        }

        public MakeConnection()
        {
          String url = "jdbc:postgresql://epi/test"
                + "?user=hs&password=irgendeines";

          try
          {
            Class.forName("org.postgresql.Driver");
            Connection conn = DriverManager.getConnection(url);

            /* eine transaktion starten */
            stmt = conn.createStatement();
            stmt.execute("START TRANSACTION");
            conn.setTransactionIsolation(8);
            System.out.println("vorher: " + countElements());

            /* Savepoint savepoint = conn.setSavepoint("savepoint_a"); */
            stmt.execute("SAVEPOINT savepoint_a");

            /* eine tabelle löschen und ein rollback durckführen */
            stmt.execute("DROP TABLE t_wert");
            stmt.execute("ROLLBACK TO SAVEPOINT savepoint_a");
            /* conn.releaseSavepoint(savepoint); */
            System.out.println("nachher: " + countElements());

            conn.rollback();
          }
          catch (Exception e)
          {
            System.out.println("Fehler: " + e.getMessage());
          }
        }

        /* counting records */
        public int countElements()
        {
            try
            {
                String query = "SELECT COUNT(*) FROM t_wert";
                ResultSet  result = stmt.executeQuery(query);
                result.next();
                return result.getInt(1);
            }
            catch (Exception e)
            { }

            return 0;
        }
}

Nach dem Aufbauen einer Datenbankverbindung starten wir eine Transaktion. Wir wollen, dass diese Transaktion im Isolation Level 'SERIALIZABLE' ausgeführt wird. Dazu verwenden wir die Methode setTransactionIsolation und übergeben den Wert '8'. JDBC erlaubt die folgenden Werte: 1, 2, 4 und 8. Die Definition des Isolation Level mit Hilfe von Zahlen ist nicht sonderlich gut, da die Lesbarkeit des Programmes sehr leiden kann. Alternativ kann man wie folgt vorgehen:

conn.setTransactionIsolation(conn.TRANSACTION_SERIALIZABLE);

JDBC definiert vier Konstanten, die anstelle der Integer Variable zu verwenden sind:

TRANSACTION_READ_COMMITTED
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE

Nach der Definition des Transaction Isolation Levels wollen wir einen Savepoint erzeugen. JDBC stellt eigene Möglichkeiten zur Verfügung, die das Erzeugen eines Savepoints sehr einfach machen (sollten). Leider unterstützt der JDBC-Treiber von PostgreSQL zum derzeitigen Zeitpunkt noch keine verschachtelten Transaktionen. Die auskommentierten Code Zeilen zeigen, wie Savepoints in Zukunft definiert werden sollen. Alternativ haben wir zum Zwecke dieses Beispieles den nötigen SQL-Code direkt abgesetzt.

Das folgende Listing zeigt den zu erwartenden Output:

[hs@hp java]$ java MakeConnection
vorher: 2
nachher: 2

http://www.postgresql.at