Manual operations with a seam of POJO

What is the best practice of using database transactions with Seam when using EJB - i.e. when deploying Seam as a WAR?

By default, Seam JavaBeans supports transactions. I can annotate a method with @Transactional that will provide the transaction. Or I can use @Transactional (NEVER) or @Transactional (MANDATORY). I can't figure out how to do this: create my own transaction, set a timeout, start, and then commit / rollback.

I tried using:

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

But it is either ignored if the transaction is already running, or it will return javax.transaction.NotSupportedException if I annotate the method with @Transactional (NEVER)

Any help appreciated. Thanks.

+6
hibernate jpa seam transactions
source share
2 answers

As you know, transaction management is a cross-cutting issue. Therefore, it is not very good that your code is scattered modulo, where these problems are not their main task.

If you use the JTA UserTransaction in a non-EJB environment, then JTA is available (Apache Tomcat does not support JTA).

1 ° rule

Seam transaction management is enabled by default for all JSF requests (Seam 2.0 +).

I think that Seam transaction management sounds better like Seam-managed Transactions . This means that Sheim takes care, behind the scenes, to urge to begin and commit. Seam plays the role of a transaction manager using the Seam transaction manager

1 ° scenario : POJO + JTA is available (Apache Tomcat does not support JTA)

Transaction Manager used by Seam: org.jboss.seam.transaction.UTtransaction

Enabled by default in non-EJB (war) environments when JTA is available (JBoss JTA support)

If you are using a JPA EntityManager or Hibernate session, you need to register them to allow Seam to manage transaction boundaries

See 9.3. Seam-driven persistence contexts , how to set up a persistent persistence context (implemented using @In)

Then enter EntityManager (EntityManager) or Session (Hibernate) using @In (with ScopeType.CONVERSATION scope)

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

Behind the scenes, the Seam Transaction Manager terminates the EntityManager (JPA) or session (Hibernate) in the active JTA UserTransaction by invoking the joinTransaction method

2 ° scenario : POJO + RESOURCE_LOCAL (either sleep mode or JPA) Transaction

Seam Transaction Manager (JPA): org.jboss.seam.transaction.EntityTransaction

Transaction Manager used by Seam (Hibernate): org.jboss.seam.transaction.HibernateTransaction

See 9.3. Seam-driven persistence contexts , how to set up a persistent persistence context (implemented using @In)

Behind the scenes, Seam Transaction Manager takes care of calling begin and commit in the underlying technology with proxies.

3 ° scenario : EJB

Transaction Manager used by Seam: org.jboss.seam.transaction.CMTTransaction

Enabled by default in an EJB environment. Take care, in this case, Seam does not control container-managed transactions.

Yours faithfully,

+8
source share

The way I am working now is as follows:

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

But if the transaction is already running and you want to join it, you use userTx.isActive (), etc.

+5
source share

All Articles