4.1 Einführung in Transaktionen im Ruhezustand

Zu all dem möchte ich Informationen zu Transaktionen hinzufügen. Wie Sie bereits wissen, handelt es sich bei einer Transaktion um eine Gruppe von Aktionen, die nur alle zusammen ausgeführt werden dürfen . Wenn eine Aktion fehlgeschlagen ist oder mit einem Fehler ausgeführt wurde, müssen alle anderen Aktionen abgebrochen werden.

Hibernate kann mit zwei Arten von Transaktionen arbeiten:

  • JDBC
  • JTA

Eine JDBC-Transaktion ist eigentlich eine Datenbanktransaktion. Es ist an die Arbeit mit der Datenbank, an die JDBC-Verbindung gebunden. Und er sorgt dafür, dass die Aktionen bei der Arbeit mit der Datenbank so ausgeführt werden, wie sie sollen: entweder alles oder nichts.

JTA – Transaktion ist eine Transaktion auf Anwendungsebene. Es ist an keine Datenbank gebunden. Seine Aufgabe besteht darin, sicherzustellen, dass bestimmte Aktionen ausgeführt werden: entweder alles oder nichts.

Beispielsweise können Sie innerhalb einer einzigen JTA-Transaktion Daten in mehrere verschiedene Datenbanken schreiben. Wenn dann ein Fehler auftritt, muss die JTA-Transaktion die Änderungen in allen Datenbanken rückgängig machen. Sogar diejenigen, die im Hinblick auf eine bestimmte Datenbank erfolgreich ausgeführt wurden.

4.2 Schnittstelle für Hibernate-Transaktionen

In der Hibernate-Bibliothek wird eine Transaktion durch die Transaction-Schnittstelle dargestellt, die unterschiedliche Implementierungen haben kann. Wenn Sie beispielsweise mit Spring arbeiten, stellt Spring einen eigenen JTA-Transaktionsmechanismus bereit.

Die Methoden dieser Schnittstelle sind:

# Methode Beschreibung
1 Start() Startet eine neue Transaktion
2 begehen() Beendet die Transaktion, überträgt/überträgt alle Änderungen
3 rollback() Setzt die aktuelle Transaktion zurück
4 setTimeout(int Sekunden) Legt die maximale Transaktionsausführungszeit fest
5 ist aktiv() Überprüft, ob eine Transaktion aktiv ist oder nicht
6 wasRolledBack() Überprüft, ob die Transaktion normal zurückgesetzt wurde
7 wasCommitted() Überprüft, ob die Transaktion normal festgeschrieben wurde
8 registerSynchronization() Registriert einen Rückruf zur Steuerung der Transaktion

Wichtig! Das Erstellen eines Transaktionsobjekts und das Starten einer Transaktion sind zwei verschiedene Dinge. Hier können Sie eine Analogie zur Thread-Klasse ziehen. Wenn Sie ein Thread()-Objekt erstellen, startet die JVM noch keinen neuen Thread. Um es zu starten, müssen Sie die start()-Methode für das Thread-Objekt aufrufen. Das Gleiche gilt für eine Transaktion – sie muss die begin()-Methode aufrufen.

Ein Beispiel dafür, wie Transaktionen normalerweise in Hibernate abgewickelt werden:


Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
try {
    transaction.begin();
    Long count = session.createQuery("select count(*) from Employee", Long.class).uniqueResult();
    transaction.commit();
}
catch (Exception e) {
	if (transaction.getStatus() == ACTIVE || transaction.getStatus() == MARKED_ROLLBACK) {
    transaction.rollback();
    }
}
finally {
	session.close();
	sessionFactory.close();
}

Wir sehen hier drei Dinge:

Zunächst wird die gesamte Arbeit mit der Datenbank durch Aufrufen von Methoden in eine Transaktion verpackt begin(). commit()Alle Aktionen zwischen Aufrufen dieser beiden Methoden müssen ausgeführt werden: entweder alle zusammen oder nichts.

Zweitens versuchen wir, wenn ein Fehler auftritt, die Transaktion rückgängig zu machen, indem wir die aufrufen rollback(). Das bedeutet, dass TransactionManger zunächst alle Aktionen zwischen begin()und aufzeichnen commit()und dann alles so zurückgeben muss, wie es wäre, wenn wir aufgerufen hätten rollback().

Übrigens ist es keine Tatsache, dass beim Aufruf der Rollback-Methode kein Fehler auftritt. Fehler passieren immer. Sie müssen diese Tatsache einfach akzeptieren und darauf vorbereitet sein.

4.3 Transaktionsmanager

Aus Sicht des Transaktionsmanagements ist Hibernate nur ein einfacher Objekt-Wrapper für JDBC. Hibernate selbst verfügt nicht über Funktionen zur Transaktionsverarbeitung. Hibernate Transaction ist eigentlich ein Wrapper für die zugrunde liegende JDBC-Transaktion (oder JTA-Transaktions-Wrapper). JDBCTransaction ist die Standardeinstellung. Beispiel aus der Hiberante-Einstellungsdatei:


hibernate.transaction.factory_class  org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class  org.hibernate.transaction.JDBCTransactionFactory

Schauen wir uns unseren Code mithilfe von Transaktionen noch einmal an:


Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the base
session.flush();
transaction.commit();
session.close();

Schauen wir uns nun den Code der JDBCTransaction-Klasse an:


public class JDBCTransaction implements Transaction {
 
    public void begin() throws HibernateException {
    	...
    	if (toggleAutoCommit) jdbcContext.connection().setAutoCommit(false);
    	...
    }
}

Dies ist die Methode zum Starten einer Transaktion. Schauen Sie sich dann die Sendemethode an:


public void commit() throws HibernateException {
    ...
    jdbcContext.connection().commit();
    ...
    jdbcContext.connection().setAutoCommit( true );
    ...
}

Ersetzen wir nun diesen Code in den Hibernate-Beispielcode:

Überwintern Einfacher JDBC-Code

Session session = sessionFactory.openSession();
Transaction transaction = session.getTransaction();
transaction.begin();
//here is your code for working with the database
session.flush();
transaction.commit();
session.close();

Connection conn = jdbcContext.connection();
conn.setAutoCommit(false);
 
//here is your database code
conn.commit ()
conn.setAutoCommit(true);
conn.close();

Native Hibernate-Transaktionen sind also lediglich native JDBC-Aufrufe an die Datenbank. Nicht mehr und nicht weniger. Aber JTA-Transaktionen sind interessanter. Aber dazu ein anderes Mal mehr.