2016-08-10 4 views
1

In Java Hibernate, wenn wir etwas mit DB tun müssen, brauchen wir: 1. Öffnen Sitzung 2. Transaktion beginnen 3. Beenden Transaktion 4. Schließen SitzungSession und Transaktion in Hibernate Java

  • zum Beispiel, wenn ich will Schülerliste erhalten:

    public static List<Student> getStudentList() 
    { 
        List<Student> l = null; 
        Session session = HibernateUtil.getSessionFactory().openSession(); 
        try { 
         String hql = "from Student"; 
         Query query = session.createQuery(hql); 
         l = query.list(); 
        } catch (HibernateException ex) { 
         //Log the exception 
         System.err.println(ex); 
        } finally { 
         session.close(); 
        } 
        return l; 
    } 
    
  • Legen Sie einen Studenten

    public static boolean addStudent(Student s) 
    { 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    
    if (... /* check if student is already exists*/) 
    { 
        return false; 
    } 
    Transaction transaction = null; 
    
    try { 
        transaction = session.beginTransaction(); 
        session.save(s); 
        transaction.commit(); 
    } catch (HibernateException ex) { 
        //Log the exception 
        transaction.rollback(); 
        System.err.println(ex); 
        } finally { 
         session.close(); 
    } 
    return true; 
    } 
    

Warum gibt es keine Transaktion in getStudentList()? Vielen Dank im Voraus

Antwort

1

Dieser Ruhezustand article erklärt das Verhalten von SELECT-Operationen, die nicht explizit innerhalb einer Transaktion ausgeführt werden.

Das folgende Beispiel wird in dem Artikel gegeben aber es gilt auch für Ihr Abfrage-Beispiel.

Sitzungssitzung = sessionFactory.openSession();
session.get (Item.class, 123l);
session.close();

  1. Eine neue Sitzung wird geöffnet. Zu diesem Zeitpunkt erhält es keine Datenbankverbindung.
  2. Der Aufruf von get() löst einen SQL SELECT aus. Die Sitzung ruft jetzt eine JDBC-Verbindung vom Verbindungspool ab. Hibernate deaktiviert standardmäßig den Autocommit-Modus für diese Verbindung mit setAutoCommit (false). Dies startet effektiv eine JDBC-Transaktion!
  3. Der SELECT wird innerhalb dieser JDBC-Transaktion ausgeführt. Die Sitzung wird geschlossen, und die Verbindung wird an den Pool zurückgegeben und von Hibernate freigegeben - Hibernate ruft close() für die JDBC-Verbindung auf. Was passiert mit der nicht übertragenen Transaktion?

Die Antwort auf diese Frage lautet: „Es hängt davon ab!“ Die JDBC-Spezifikation nichts über schwebende Geschäfte nicht sagen, wann close() auf eine Verbindung aufgerufen wird. Was passiert, hängt davon ab, wie die Anbieter die Spezifikation implementieren. Bei Oracle JDBC-Treibern beispielsweise wird der Aufruf von close() die Transaktion bestätigen! Die meisten anderen JDBC-Anbieter nehmen die gleiche Route und führen eine ausstehende Transaktion zurück, wenn das JDBC-Verbindungsobjekt geschlossen und die Ressource an den Pool zurückgegeben wird. Offensichtlich ist dies kein Problem für die SELECT sein [...]

Ermöglicht das obige Beispiel erweitern ein mögliches Problem zu provozieren.

Session session = sessionFactory.openSession(); 
Item item = session.get(Item.class, 123l); 
item.setPrice(10); 
session.close(); 

Jetzt hängt es von den JDBC-Treiber, wenn der neue Preis für die Item beibehalten wird oder nicht.

So können Sie Begin und Commit-Transaktionen auf reinen SELECT Operationen vernachlässigen, auch wenn Ihr JDBC-Treiber die Transaktion Rollback, solange Sie keine Datenbankänderungen haben.

Aber trotzdem würde ich stark empfehlen, Transaktionen bei jeder Operation zu verwenden, um Missverständnisse und Probleme zu vermeiden.

Verwandte Themen