1 Reply Latest reply on Apr 18, 2013 9:36 AM by ronaldocwb

    Keep a UserTransaction through many requests

    ronaldocwb

      Hi,

       

      I need to keep a UserTransaction through many requests in a CDI/JSF application (WAR). I have tried many ways but i can't attach my transaction to my conversational bean. See the example below:

       

      It's a simple CDI application deployed on JBossAS 7.1.

       

      My Bean:

       

       

      @Named
      @ConversationScoped
      public class TestBean implements Serializable {
      
      
                private static final long serialVersionUID = 759936979473538251L;
        
                @Inject
                private UserTransaction userTransaction;
        
                @Inject
                Conversation conversation;
        
                protected Logger log = Logger.getLogger(TestBean.class);
        
                public void begin() throws Exception{
                          conversation.begin();
                          try {
                                    userTransaction.begin();
                          } catch (Exception e) {
                                    e.printStackTrace();
                          }
                          logStatus();
                }
        
                public void doSomeAction() throws Exception{
                          log.info("Doing some action...");
                          logStatus();
                }
        
                private void logStatus() throws Exception {
                          log.info("Conversation: " + conversation.getId());
                          log.info("Transaction status: " + userTransaction.getStatus());
                }
      }
      

       

       

      My XHTML file:

       

       

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
      <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:ui="http://java.sun.com/jsf/facelets"> 
      
      
      <h:head></h:head> 
      <body>
          <h:form>
                    <h:commandButton action="#{testBean.begin()}" value="Begin" />
                    <h:commandButton action="#{testBean.doSomeAction()}" value="Do some action!" />
          </h:form>
      </body> 
      </html>
      
      

       

      Log output:

      Transaction status 0 => ACTIVE

      Transaction status 6 => NO_TRANSACTION

       

      16:17:16,474 INFO  [br.com.veere.bean.TestBean] (http-localhost-127.0.0.1-8080-2) Conversation: 1
      16:17:16,476 INFO  [br.com.veere.bean.TestBean] (http-localhost-127.0.0.1-8080-2) Transaction status: 0
      16:17:16,485 ERROR [org.jboss.as.txn] (http-localhost-127.0.0.1-8080-2) JBAS010152: APPLICATION ERROR: transaction still active in request with status 0
      16:17:19,096 INFO  [br.com.veere.bean.TestBean] (http-localhost-127.0.0.1-8080-2) Doing some action...
      16:17:19,097 INFO  [br.com.veere.bean.TestBean] (http-localhost-127.0.0.1-8080-2) Conversation: 1
      16:17:19,098 INFO  [br.com.veere.bean.TestBean] (http-localhost-127.0.0.1-8080-2) Transaction status: 6
      

       

      At the point that transaction have the status 6 I needed to continue the same transaction that I started.

      I've serched by this error (JBAS010152) but I didn't get any solution.

       

      Sample eclipse project and war file attached.

       

      Is there any solution to this case?

        • 1. Re: Keep a UserTransaction through many requests
          ronaldocwb

          Just posting for history, maybe can help somebody.

           

          The solutions that worked for me was:

           

          1. Use a @Stateful EJB instead of a @Named component. It will keep the transaction active as long as you work with this EJB and don't commit or rollback the Transaction.

            => This is the easier way.

           

           

          2. Keep using a CDI @Named bean and create a interceptor that injects the TransactionManager and when before the method call it resumes the transaction and after it suspends the transaction.

            => This solution can couse some troubles, like when you inject one CDI bean into another and both use this interceptor.