14 Replies Latest reply on Aug 29, 2009 9:07 AM by Stuart Douglas

    usage of UTTransaction

    Arbi Sookazian Master

      This:


      UTTransaction utx = new UTTransaction();

      is not allowed b/c there is no constructor for this class according to Eclipse.


      This:


      @In(create=true) 
      private UTTransaction utx;



      results in:


      Caused by: org.jboss.seam.RequiredException: @In attribute requires non-null value: equipmentProcessingView.utx



      In table 9.3 of SiA, UTTransaction is Default in non-EJB environment.  Native tx mgr is Application-managed JTA UserTransaction.


      I have a WAR project and am using JavaBean components.


      So how can I use this class to programmatically demarcate tx begin and commit (BMP style)??


      There are no examples with UTTransaction in the 2.2.0.GA distro.


      How do I use this?  I'm pretty sure I don't need to configure anything in components.xml like


      <tx:entity-transaction entity-manager="#{em}"/>



      b/c I'm using the default in a non-EJB envmt...

        • 1. Re: usage of UTTransaction
          Arbi Sookazian Master

          I lied:


          UTTransaction(javax.transaction.UserTransaction delegate)
             {
                this.delegate = delegate;
                if (delegate==null)
                {
                   throw new IllegalArgumentException("null UserTransaction");
                }
             }



          but this is not visible to my class.


          ???


          Can I use a different class (or inject one) like javax.transaction.UserTransaction directly?

          • 2. Re: usage of UTTransaction
            Stuart Douglas Master

            try:


            @In(value="org.jboss.seam.transaction.transaction") UserTransaction userTransaction;
            
            



            UTTransaction implements UserTransaction

            • 3. Re: usage of UTTransaction
              Arbi Sookazian Master


              First the bad news





              I tried this:


              @In(value="org.jboss.seam.transaction.transaction")
              org.jboss.seam.transaction.UserTransaction userTransaction;



              and got this:


              2009-08-28 08:20:35,087 DEBUG [org.jboss.seam.transaction.UTTransaction] beginning JTA transaction
              2009-08-28 08:20:35,087 DEBUG [org.jboss.seam.Component] instantiating Seam component: org.jboss.seam.core.interpolator
              2009-08-28 08:20:35,087 DEBUG [org.jboss.seam.Component] initializing new instance of: org.jboss.seam.core.interpolator
              2009-08-28 08:20:35,087 DEBUG [org.jboss.seam.Component] done initializing: org.jboss.seam.core.interpolator
              2009-08-28 08:20:35,087 ERROR [com.cox.ers.session.EquipmentProcessingViewAction] error occurred: 
              javax.transaction.NotSupportedException
                   at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:79)
                   at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.begin(BaseTransactionManagerDelegate.java:77)
                   at org.jboss.tm.usertx.client.ServerVMClientUserTransaction.begin(ServerVMClientUserTransaction.java:124)
                   at org.jboss.seam.transaction.UTTransaction.begin(UTTransaction.java:39)
                   ....



              I noticed while I was stepping thru the org.jboss.seam.transaction.Transaction class that getTransaction() is called possibly dozens of times due to the @Unwrap annotation.  Is this really necessary?  The scope is EVENT for this component. 


              The other stupidity is that there are no local or instance variables defined in that class (for brevity I assume) and there are no logging statements.  So I can't see in the debugger what's going on.  That sucks.


              Anyways, here's what I'm doing after injection of UserTransaction instance:


              private void insertStatusAndErsNote(){
                        try {
                             
                             userTransaction.begin();
                              }
              ...
              }




              NotSupportedException - Thrown if the thread is already associated with a transaction and the Transaction Manager implementation does not support nested transactions.

              http://72.5.124.55/javaee/5/docs/api/javax/transaction/UserTransaction.html#begin%28%29


              so I changed this:


              <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>



              to this:


              <core:init debug="@debug@" jndi-pattern="@jndiPattern@" transaction-management-enabled="false"/>



              on to the good news....

              • 4. Re: usage of UTTransaction
                Arbi Sookazian Master

                Now for the GOOD news!



                Here's a summary of the pertinent class/code.  There is no active tx running when apply() is executed b/c I turned off global tx's in components.xml (which may end up being a bad thing).  So now I have finally solved the requirement in terms of tx management: the web service is invoked w/o a tx and the local CRUD operations are invoked inside a tx using Seam's BMT.  The web service call fails (as intentionally configure to do so with bad credentials, etc.) but the inserts and update are successful to local DB.


                I guess if I really wanted to, I could wrap the web service call in a tx of its own but I don't think it's necessary.


                Thanks to Stuart and Francisco for help in this thread and the other two related threads!


                Please identify any potential problems with this approach (i.e. turning off global tx's).  thx.


                @Name("equipmentProcessingView")
                @Scope(ScopeType.CONVERSATION)
                @ProfilingThisClass
                public class EquipmentProcessingViewAction implements Serializable {
                
                     @In(value="org.jboss.seam.transaction.transaction", required=false) 
                     UserTransaction userTransaction;
                
                     @In     
                     private EntityManager entityManager;
                     
                     @Transactional(TransactionPropagationType.NEVER)  //doing this to make sure no active tx exists when this method is called
                     @End
                     public void apply() {          
                          callWebService();          
                          insertStatusAndErsNote();
                     }
                
                     private void callWebService(){
                          progressBarWebService.startProcess();
                          progressBarLocalDB.startProcess();          
                     }
                
                     private void insertStatusAndErsNote(){     
                          try {                              
                               userTransaction.begin();               
                               entityManager.joinTransaction();     
                                        //do some CRUD work
                                        entityManager.flush();
                               }
                               catch(Exception e){
                                     //handle exception
                               }
                      }
                
                
                }

                • 5. Re: usage of UTTransaction
                  Arbi Sookazian Master

                  So here's a potential problem of disabling global tx's according to SiA:



                  But even with a conversation-
                  scoped persistence manager, you still face the problem that without explicit transaction
                  boundaries defined, lazy-load operations execute in autocommit mode,
                  opening and closing a transaction for every query. Not only is this expensive, it also
                  lacks isolation guarantees.

                  Is it possible to disable global tx's on a per-component or per-page (or multiple components or pages) basis?


                  Does anybody routinely disable global tx's?

                  • 6. Re: usage of UTTransaction
                    Francisco Jose Peredo Noguez Master

                    Stuart Douglas wrote on Aug 28, 2009 05:37:


                    try:

                    @In(value="org.jboss.seam.transaction.transaction") UserTransaction userTransaction;
                    
                    



                    UTTransaction implements UserTransaction


                    Or if  you prefer to do things programmatically:


                    import org.jboss.seam.transaction.Transaction;
                    
                    UserTransaction userTransaction  =  Transaction.instance()
                    

                    • 7. Re: usage of UTTransaction
                      Francisco Jose Peredo Noguez Master

                      Arbi Sookazian wrote on Aug 28, 2009 18:13:


                      Is it possible to disable global tx's on a per-component or per-page (or multiple components or pages) basis?

                      Does anybody routinely disable global tx's?


                      Have you tried with @BypassInterceptors ?

                      • 8. Re: usage of UTTransaction
                        Arbi Sookazian Master

                        Francisco Peredo wrote on Aug 28, 2009 19:26:



                        Arbi Sookazian wrote on Aug 28, 2009 18:13:


                        Is it possible to disable global tx's on a per-component or per-page (or multiple components or pages) basis?

                        Does anybody routinely disable global tx's?


                        Have you tried with @BypassInterceptors ?


                        No, I did not even think of trying that.  That would disable bijection as well but I guess I can work around that.  So do you think using @BypassInterceptors would actually turn off the global tx's as well?  I guess I could try by testing with the @Transactional(TransactionPropagationType.NEVER) (if it's on then an exception will be thrown).


                        What else is disabled?  Looks like ConversationalInterceptor and SynchronizationInterceptor at minimum.


                        Somebody should write a wiki article on what exactly happens when you use @BypassInterceptors...

                        • 9. Re: usage of UTTransaction
                          Francisco Jose Peredo Noguez Master

                          Arbi Sookazian wrote on Aug 28, 2009 20:39:



                          I guess I could try by testing with the @Transactional(TransactionPropagationType.NEVER) (if it's on then an exception will be thrown).




                          AFAIK @Transactional(TransactionPropagationType.NEVER) also dependes on the transactional interceptor being enabled

                          • 10. Re: usage of UTTransaction
                            Francisco Jose Peredo Noguez Master

                            I guess you could use: Transaction.instance().isActive()

                            • 11. Re: usage of UTTransaction
                              Arbi Sookazian Master

                              Is there a JIRA for selectively turning on/off global tx's?  And would anybody else even need to use this type of functionality?

                              • 12. Re: usage of UTTransaction
                                Stuart Douglas Master

                                There is no JIRA that I am aware of but I think it would be a good idea, especially if it was enabled/disabled through pages.xml.

                                • 14. Re: usage of UTTransaction
                                  Stuart Douglas Master

                                  Francisco Peredo wrote on Aug 28, 2009 19:26:


                                  Have you tried with @BypassInterceptors ?


                                  Global transactions are implemeted using a jsf phase listener not an interceptor, so BypassInterceptors should have no effect.