2009-11-24 6 views
6

Was ist die beste Vorgehensweise für die Verwendung von Datenbanktransaktionen mit Seam, wenn keine EJBs verwendet werden - dh. bei der Bereitstellung von Seam als WAR?Manuelle Transaktionen mit Naht POJO

Standardmäßig unterstützen Seam JavaBeans Transactions. Ich kann eine Methode mit @Transactional annotieren und sicherstellen, dass eine Transaktion erforderlich ist. Oder ich kann @Transactional (NEVER) oder @Transactional (MANDATORY) verwenden. Was ich nicht herausfinden kann, ist, eine eigene Transaktion zu erstellen, ein Timeout zu setzen, zu beginnen und dann zu committen/rollback.

Ich habe versucht, mit:

UserTransaction utx = Transaction.instance(); 
utx.setTransactionTimeout(2000); 
utx.begin(); 

Aber es wird entweder ignoriert, wenn eine Transaktion bereits im Gang ist oder gibt ein javax.transaction.NotSupportedException wenn ich die Methode mit @Transactional (NIE)

mit Anmerkungen versehen

Jede Hilfe wird geschätzt. Vielen Dank.

+0

geben den vollständig qualifizierten Namen von @Transactional – Bozho

+0

org.jboss.seam.annotations.Transactional – Damo

Antwort

8

Wie Sie wissen, ist das Transaktionsmanagement ein Querschnittsthema. Es ist also keine gute Idee, dass Ihr Code in Modulen verstreut ist, in denen diese Bedenken nicht ihre Hauptanliegen sind.

Wenn Sie eine JTA UserTransaction in einer Nicht-EJB-Umgebung verwenden, ist JTA verfügbar (Apache Tomcat unterstützt JTA nicht).

1 ° Regel

Seam Transaktionsmanagement ist standardmäßig für alle JSF-Anfragen (Seam 2.0+) aktiviert.

Ich denke Seam Transaktionsmanagement von Seam verwaltet besser als Transaktionen klingt. Es bedeutet, Seam kümmert sich hinter den Kulissen darum, anzufangen und zu begehen. Naht spielt die Rolle des Transaktionsmanager durch eine Naht Transaction Manager mit

1 ° Szenario: POJO + JTA avaliable (Apache Tomcat nicht unterstützt JTA)

Manager-Transaktion, die von Seam: org.jboss.seam .transaction.UTtransaction

standardmäßig in nicht-EJB-Umgebung (Kriegs-) aktiviert, wenn JTA verfügbar (JBoss Support JTA)

Wenn Sie JPA EntityManager oder Hibernate Session verwenden, müssen Sie sich registrieren zu können Seam verwalten Transaktionsgrenzen

Siehe 9.3. Seam-managed persistence contexts, wie eine Naht gesteuerter Persistenz Kontext einzurichten (Injected von @in verwenden)

Dann injiziert eine EntityManager (EntityManager) oder Session (Hibernate) von @in (scoped zu ScopeType verwenden.GESPRÄCH)

@Name("businessService") 
public class BusinessServiceImpl implementes BusinessService { 

    @In 
    private EntityManager entityManager; 

    public void doSomething() { 
     // You do not need to call entityManager().getTransaction().begin(); 
     // because Seam Transaction Manager takes care of it 
     // By using proxies 
     // Therefore, if you call entityManager().getTransaction().begin() 
     // You will get IllegalStateException 

     // Some EntityManager operations persist, find etc 

     // You do not need to call entityManager().getTransaction().commit(); 
     // because Seam Transaction Manager takes care of it 
     // By using proxies 
    } 

} 

Hinter den Kulissen Seam Transaction Manager die EntityManager (JPA) oder Session (Hibernate) in der aktiven JTA Usertransaction anwerben, durch den Aufruf joinTransaction Methode

2 ° Szenario: POJO + RESOURCE_LOCAL (Entweder Hibernate oder JPA) Transaktion

Manager-Transaktion, die von Seam (JPA): org.jboss.seam.transaction.EntityTransaction

Transa ction-Manager, die von Seam (Hibernate): org.jboss.seam.transaction.HibernateTransaction

9.3. Seam-managed persistence contexts Sehen Sie, wie eine Naht gesteuerter Persistenz Kontext einzurichten (Injected von @in verwenden)

Hinter den Kulissen Seam Transaktion Manager kümmert sich um mithilfe von Proxys

3 ° Szenario in der zugrunde liegenden Technologie Aufruf beginnen und sich verpflichten: EJB

Transaction Manager, die von Seam: org.jboss.seam.transaction.CMTTransaction

In der EJB-Umgebung standardmäßig aktiviert. Achten Sie darauf, dass Seam in diesem Fall keine Container-gesteuerte Transaktion steuert.

Grüßen,

5

Die Art und Weise arbeite ich zur Zeit ist wie folgt:

//don't use @Transactional annotation 
public void doStuff() { 
    UserTransaction userTx = (UserTransaction) org.jboss.seam.Component.getInstance("org.jboss.seam.transaction.transaction"); 
    userTx.setTransactionTimeout(10 * 60); //set timeout to 60 * 10 = 600 secs = 10 mins 
    userTx.begin(); 

    /*If entity manager is created before the transaction is started (ie. via Injection) then it must join the transaction */ 
    entityManager.joinTransaction(); 

    //do stuff  

    entityManager.persist(user); 
    entityManager.flush(); //logs will show an insert at this point 

    userTx.commit(); //or rollback() 
} 

Aber wenn eine Transaktion bereits im Gange ist und Sie wollen es beitreten dann verwenden Sie die userTx.isActive() etc

+0

Excellent Mann !!! Ich könnte dies verwenden, um die Ausnahme "Transaktion ist nicht aktiv" zu vermeiden. – prageeth