wake-up-neo.com

Können Sie mehrere Transaktionen in einer Hibernate-Sitzung durchführen?

Können Sie mehrere Transaktionen in einer Hibernate-Sitzung durchführen?

Ich bin mir nicht sicher, ob dies zulässig ist. In meinem Code habe ich einen langen Thread und nimmt Elemente aus einer Blockierungswarteschlange. Abhängig davon, was sich in der Warteschlange befindet, muss möglicherweise ein Ruhezustandobjekt erstellt und gespeichert werden, oder es muss möglicherweise nichts getan werden. 

Jedes Element ist unterschiedlich. Wenn Element 1 gespeichert wird und Artikel 2 nicht gespeichert wird, kann der Grund nicht gespeichert werden, aus dem ich nicht möchte, um das Hinzufügen von Element 1 zur Datenbank zu verhindern. 

Am einfachsten ist dies für jedes Element, das zum Erstellen einer neuen Sitzung, zum Öffnen einer Transaktion, zum Speichern eines neuen Objekts, zum Festschreiben einer Transaktion und zum Schließen einer Sitzung erstellt werden muss

Das bedeutet jedoch, dass für jedes Element eine neue Sitzung erstellt wird. Dies scheint gegen die eigenen Empfehlungen von Hibernates zu verstoßen, so dass das Session Per Request Pattern nicht verwendet wird. Daher bestand meine Alternative darin, eine Sitzung im Thread zu erstellen, dann einfach eine neue Transaktion zu öffnen und festzuschreiben, wenn dies zum Erstellen eines neuen Objekts erforderlich ist. Ich habe jedoch keine Beispiele für diesen Ansatz gesehen und bin mir nicht sicher, ob er tatsächlich funktioniert. 

22
Paul Taylor

Das Session-per-Request-Muster verwendet eine JDBC-Verbindung pro Sitzung, wenn Sie lokale Transaktionen ausführen. Bei JTA werden die Verbindungen nach jeder Anweisung aggressiv freigegeben, um für die nächste Anweisung erneut erworben zu werden.

Die Hibernate-Transaktions-API delegiert das begin/commit/rollback an die JDBC-Verbindung für lokale Transaktionen und an die zugehörige UserTransaction für JTA . Daher können Sie mehrere Transaktionen in derselben Hibernate-Sitzung ausführen, aber es gibt einen Haken. Sobald eine Ausnahme ausgelöst wird, können Sie diese Sitzung nicht mehr verwenden.

Mein Rat ist zu teilen und zu erobern. Teilen Sie einfach alle Elemente auf, konstruieren Sie ein Befehlsobjekt für jedes dieser Objekte und senden Sie sie an einen ExecutorService#invokeAll . Verwenden Sie die zurückgegebene Liste, um zu iterieren, und rufen Sie Future#get() auf, um sicherzustellen, dass der ursprüngliche Thread wartet, nachdem alle Stapeljobs abgeschlossen wurden. 

Die ExecutorService sorgt dafür, dass Sie alle Befehle gleichzeitig ausführen, und für jeden Befehl sollte ein Dienst verwendet werden, der seinen eigenen @Transaction verwendet. Da Transaktionen Thread-gebunden sind, werden alle Batch-Jobs isoliert ausgeführt .

22
Vlad Mihalcea

Natürlich kannst du. Eine Ruhezustandsitzung ist mehr oder weniger eine Datenbankverbindung und ein Cache für Datenbankobjekte. Sie können mehrere aufeinanderfolgende Transaktionen in einer einzigen Datenbankverbindung ausführen. Wenn Sie einen Verbindungspool verwenden, wird die Verbindung nicht geschlossen, sondern wiederverwendet.

Ob Sie sollten oder nicht, ist eine Frage der Wiederverwendung von Objekten aus der Sitzung. Wenn eine gute Chance besteht, Sie jedoch Objekte wiederverwenden können, die eine vorherige Transaktion in eine Sitzung eingefügt hat, sollten Sie eine einzige Sitzung für mehrere Transaktionen beibehalten. Wenn ein Objekt jedoch einmal festgeschrieben wurde, wird es nie wiederverwendet. Es ist sicherlich besser, die Sitzung zu schließen und ein neues Objekt erneut zu öffnen oder es einfach zu löschen.

Wie es geht :

Wenn Sie ein Session-Objekt haben, erstellen Sie Transaktionen mit:

Transaction transaction;
transaction = session.beginTransaction();
... (operations in the context of transaction)
transaction.commit();
... (other commands outside of any transaction)
transaction = session.beginTransaction();
... (and so on and so forth ...)
11
Serge Ballesta

Aus der Winterschlaf-Dokumentation 

"Eine Sitzung ist ein kostengünstiges, nicht threadsicheres Objekt, das einmalig verwendet und anschließend verworfen werden sollte: für eine einzelne Anforderung, eine Konversation oder eine einzelne Arbeitseinheit. Eine Sitzung erhält keine JDBC-Verbindung oder eine Datenquelle, sofern dies nicht der Fall ist Es wird keine Ressourcen verbrauchen, bis es verwendet wird. "

wenn Sie also immer wieder Sitzungen erstellen, wird dies das System nicht stark belasten. Wenn Sie eine Sitzung zu lange fortsetzen, kann dies zu Problemen führen, da die Sitzung nicht threadsicher ist. Meiner Meinung nach ist die einfachste Lösung die beste. "Der einfachste Weg, dies zu tun, ist für jedes Element, das erstellt werden muss, um ein neues zu erstellen Sitzung, Transaktion öffnen, neues Objekt speichern, Transaktion festschreiben, Sitzung schließen "

Übrigens, wenn Sie eine einzelne Aufzeichnung von etwas erstellen, benötigen Sie keine Transaktion zu sehr. Das Erstellen eines einzelnen Datensatzes ist von Natur aus "alles oder nichts", wofür wir die Transaktion verwenden

3
faisalbhagat
package hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
class Tester {
public static void main(String[] args) {
    SessionFactory sf = new org.hibernate.cfg.Configuration().configure().buildSessionFactory(new StandardServiceRegistryBuilder().configure().build());
    Session session = sf.openSession();
    session.beginTransaction();
        Student student = new Student();
    student.setName("Mohammad Faizan");
    student.setRollNo(1309114040);
        session.save(student);
    session.getTransaction().commit();
    session.getTransaction().begin();
    session.load(Student.class,23);
    student.setName("New Name");
    student.setRollNo(123);
    session.update(student);
    session.getTransaction().commit();
    session.close();
  }
}
0
Faizan Mohammad

Die kurze Antwort lautet Ja, Sie können dieselbe Sitzung für die Transaktion verwenden. Werfen Sie einen Blick auf org.hibernate.Transaction., Die Methode zur Verwaltung der Transaktion ist erforderlich.

0
Vinay