2009-11-24 12 views
6

Qual è la procedura migliore per utilizzare le transazioni del database con Seam quando non si utilizzano EJB, ad es. quando si distribuisce Seam come WAR?Transazioni manuali con Seam POJO

Per impostazione predefinita, Seam JavaBeans supporta le transazioni. Posso annotare un metodo con @Transactional e ciò garantirà che sia necessaria una transazione. O posso usare @Transactional (NEVER) o @Transactional (OBBLIGATORIO). Quello che non riesco a scoprire come fare è creare la mia Transazione, impostare un timeout, iniziare e poi eseguire il commit/rollback.

Ho provato con:

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

ma è ignorato se una transazione è già in corso o restituisce un javax.transaction.NotSupportedException se annotare il metodo con @Transactional (MAI)

Qualsiasi aiuto apprezzato. Grazie.

+0

danno il nome completo del @Transactional – Bozho

+0

org.jboss.seam.annotations.Transactional – Damo

risposta

8

Come sapete, la gestione delle transazioni è una preoccupazione trasversale. Quindi non è una buona idea che il tuo codice sia sparpagliato nei moduli in cui tali preoccupazioni non sono la loro preoccupazione principale.

Se si utilizza JTA UserTransaction in un ambiente non EJB, quindi JTA è disponibile (Apache Tomcat non supporta JTA).

1 ° regola

gestione delle transazioni di Seam è abilitato di default per tutte le richieste JSF (Seam 2.0+).

Penso Seam la gestione delle transazioni suona meglio come transazioni gestite da Seam. Significa che Seam prende cura, dietro le quinte, delle chiamate begin e commit. Seam interpreta il ruolo di gestore delle transazioni utilizzando un Seam Transaction Manager

1 ° scenario: POJO + JTA available (Apache Tomcat non supporta JTA)

Transaction Manager utilizzato da Seam: org.jboss.seam .transaction.UTtransaction

abilitato di default in ambiente non EJB (guerra) quando JTA disponibili (JBoss supporto JTA)

Se si utilizza JPA EntityManager o Hibernate Session, è necessario registrarsi loro di gestire consente Seam confini delle transazioni

Vedi 9.3. Seam-managed persistence contexts come impostare un contesto di persistenza gestito da Seam (iniettata utilizzando @In)

poi iniettare un EntityManager (EntityManager) o Session (Hibernate) utilizzando @In (ambito a ScopeType.CONVERSAZIONE)

@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 
    } 

} 

Dietro le quinte, Seam Transaction Manager arruolare l'EntityManager (JPA) o Session (Hibernate) nella attiva JTA UserTransaction, chiamando joinTransaction metodo

2 ° scenario: POJO + RESOURCE_LOCAL (o Hibernate o JPA) Transaction

Transaction manager utilizzato da Seam (JPA): org.jboss.seam.transaction.EntityTransaction

Transa ction Manager utilizzato da Seam (Hibernate): org.jboss.seam.transaction.HibernateTransaction

Vedi 9.3. Seam-managed persistence contexts come impostare un contesto di persistenza gestito da Seam (iniettata utilizzando @In)

Dietro le quinte, Transaction Seam Responsabile si prende cura di chiamare iniziano e si impegnano nella tecnologia sottostante utilizzando proxy

3 ° scenario: EJB

Transaction manager utilizzata da Seam: org.jboss.seam.transaction.CMTTransaction

Abilitato per impostazione predefinita in ambiente EJB. Fare attenzione, in tal caso, Seam non controlla la transazione gestita dal contenitore.

saluti,

5

Il modo in cui sto lavorando è come questo:

//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() 
} 

Ma se una transazione è già in corso e si desidera farne parte allora si utilizza l'userTx.isActive() ecc

+0

eccellente uomo !!! Potrei usarlo per evitare l'eccezione "Transaction is not active". – prageeth