-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Wiki Eintrag zu "Sessions and transactions"
PostPosted: Wed Oct 18, 2006 3:07 pm 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
Ich habe vorhin im Hibernate Wiki den Artikel zu "Sessions and transactions" gelesen: http://www.hibernate.org/42.html

Im Abschnitt "Transaction demarcation with JTA" gibt es 2 Codebeispiele und beim zweiten Beispiel frage ich mich, ob das wirklich so hinhaut oder nicht vielleicht was vergessen wurde (weil der Code ja nur das Konzept verdeutlichen soll).


Code:
// code from the Hibernate wiki

UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");

Session session = factory.openSession();

try {
    tx.begin();

    // Do some work
    session.load(...);
    session.persist(...);

    session.flush();

    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}
finally {
    session.close();
}




In dem zweiten Codebeispiel (siehe oben) wird zunächst eine Hibernate Session erzeugt, die dann vom Programmierer selber verwaltet (gemänaged) wird. Das geschieht noch ausserhalb einer Transaktion.

Anschliessend wird dann mittels der über JNDI erfragten UserTransaction eine JTA-Transaction begonnen und innerhalb dieser Entities geladen und gespeichert (session.load(), session.find()). Anschliessend wird dann die Session geflushed ( session.flush() ) und danach dann die Transaktion commited ( tx.commit() ).

Unklar ist mir, wie jetzt die Hibernate Session überhaupt an dieser Transaktion teilnimmt. Denn sie wurde ja bereits eröffnet, als die JTA-Transaktion noch gar nicht begonnen wurde.


Beim Aufsetzen auf JPA wäre die Analogie zum Codebeispiel aus dem Hibernate-Wiki die Verwendung eines application-managed Entity Managers. In JPA gibt es dazu die Regel, dass wenn ein Application-Managed EntityManager innerhalb einer Transaktion erzeugt wird, er automatisch an diese Transaktion gebunden wird, sodass beim Transaction Commit der PersistenceContext mit der Datenbank synchronisiert wird. Wenn ein Application-Managed EntityManager jedoch ausserhalb einer Transaktion erzeugt wird, also bevor eine JPA Transaction gestartet wurde, dann muss er später von Hand an diese JTA Transaction gebunden werden, damit eine Synchronisierung des PersistenceContextes erfolgt. Das erfolgt durch einen Expliziten Aufruf von EntityManager.joinTransaction().


Ungefähr würde das mit JPA so aussehen:
Code:
// comparable pattern with JPA

@Stateful
public class JPAExampleBean {
   @PersistenceUnit(unitName="xxx")
   EntityManagerFactory emf;
   EntityManager  em;

   public void init() {

      // application-managed EntityManager created outside of a transaction
      em = emf.createEntityManager();
      ...
   }


   public void persistSomeEntity(Entity e) {
     // as the EntityManager was created outside of a transaction,
     // we need to call em.joinTransaction(); in order to synchronize
     // the persistence context with the database when the transaction
     // commits.

     em.joinTransaction();
     em.persist(e);
     ...
   }

   ... more methods of the StateFul Session Bean...

  @Remove
  public void finish () {
   ...
  }

}




Zurück zum oben zitierten Code-Beispiel aus dem Hibernate-Wiki:

Ein explizites Binden der Hibernate Session an die JTA Transaktion fehlt dort. Die Frage ist also: Wie erfolgt dann diese Bindung?

Bzw. anders ausgedrückt: Führt vielleicht eine der aufgerufenen Hibernate Methoden ( session.load(), session.persist(), session.flush() ) vielleicht die Bindung durch?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 18, 2006 3:46 pm 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
Quote:
Führt vielleicht eine der aufgerufenen Hibernate Methoden ( session.load(), session.persist(), session.flush() ) vielleicht die Bindung durch?



Es sieht wohl so aus, als ob die flush() Method das macht.

Deswegen wird wohl auch ein expliziter flush()-Aufruf benötigt, ansonsten würde ein flush() ja auch bereits automatisch beim Transaction commit erfolgen.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 3:41 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
Wenn ein Application-Managed EntityManager jedoch ausserhalb einer Transaktion erzeugt wird, also bevor eine JPA Transaction gestartet wurde, dann muss er später von Hand an diese JTA Transaction gebunden werden, damit eine Synchronisierung des PersistenceContextes erfolgt. Das erfolgt durch einen Expliziten Aufruf von EntityManager.joinTransaction()


Ja, das steht so in der Spezifikation fuer die EM API. Hibernate selbst ist aber smarter, dass kann das JDBC Subsystem in Hibernate automatisch.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 19, 2006 6:35 am 
Newbie

Joined: Wed Oct 18, 2006 12:30 pm
Posts: 8
Danke für die Bestätigung, dass meine gemachte Vermutung richtig ist (siehe auch meine gestern gemachte ausführlichere Begründung in meinem englischen Beitrag dazu
http://forum.hibernate.org/viewtopic.php?t=966119 )


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.