2016-05-03 13 views
0

Angenommen, ich habe eine verwaltete Bean und ich habe eine EntityManager definiert. Ich habe mich gefragt, wie Transaktionen funktionieren und wie sie sich in verschiedenen Situationen verhalten. Aus der Dokumentation habe ich verstanden, dass flush() tatsächlich verwendet wird, um die Verzögerung beim Commit zu überschreiben und sofort zu tun. Im Beispiel unten erwartete ich also demo in der DB und demo2 nicht zu bestehen. Aber es scheint, dass alles als eine einzige Transaktion gesehen wird (von meinem Verständnis her). Warum passiert dies? Warum werden keine weiteren Annotations- oder Hibernate-Methoden von begin() und commit() benötigt, um den Beginn und das Ende der Transaktion zu definieren? Ich fühle mich wie verwirrend verschiedene Dinge hier bin ...Rollback auf JTA-Transaktionen

@Stateless 
public class Testing { 
    @PersistenceContext(unitName = "testDB") 
    private EntityManager em; 

    public void doSomeWork(){ 
     Demo demo = new Demo(); 
     em.persist(demo); 
     em.flush(); 
     //some code that makes it crash 
     Demo demo2 = new Demo(); 
     em.persist(demo2); 
     em.flush(); 
    } 
} 

Antwort

1

Wenn Container managed transactions alle Session Beans verwenden, sind standardmäßig laufen innerhalb der Transaktion. Das bedeutet, wenn eine Ausnahme auftritt, die dazu führt, dass die Transaktion zurückgesetzt wird, werden auch die Änderungen an demo zurückgesetzt.

Hier einige nützliche Informationen darüber, wie flush() Werke: https://en.wikibooks.org/wiki/Java_Persistence/Persisting#Flush

+0

Wie wird „innerhalb der Transaktion“ angegeben? Habe ich für jeden Methodenaufruf eine einzige Transaktion? Was ist, wenn zwei Anrufe nacheinander irrelevant sind und der zweite fehlschlägt? Wird das erste Rollback auch sein? – Rakim

+0

Es hängt davon ab, wie Sie es angeben - standardmäßig hat jede Methode das Transaktionsattribut "Erforderlich". Das heißt, wenn eine Transaktion bereits vorhanden ist, wird sie verwendet, wenn sie nicht vorhanden ist, wird sie erstellt. Sie können dies jedoch ändern, indem Sie die Annotation 'javax.ejb.TransactionAttribute' verwenden, z. B. so, dass jedes Mal eine neue Transaktion erstellt wird oder gar keine Transaktion verwendet wird. – rapasoft

+0

Ich wollte eine neue Transaktion für jeden einzelnen Methodenaufruf (Anrufe von außerhalb der Bean) haben. Ich habe die Dokumentation durchgelesen, die Sie verlinkt haben, aber ich bin nicht wirklich damit vertraut. Ist die Standardkonfiguration ausreichend? – Rakim