5 Replies Latest reply on Oct 12, 2007 8:13 AM by subramaniam.venkat

    Transaction not allowed

    subramaniam.venkat

      Hello All,

      I have exposed an SLSB as an web-service.
      There is no transaction on this SLSB which i have implemented.

      But this SLSB makes calls to Springs Beans on which transaction has been implemented.

      I am getting the below error and i am not able to find a reason for this.

      I am using Jboss-4.0.3-SP1 and JDK142.

      I am using Required transaction attribute when i am creating a transaction with Spring. This behaves the same way as the Required transaction attribute in CMT.

      And the transaction attribute in the EJB is also "Required". So in theory there must not be a new transaction which should be created by Spring and the same transaction which has been created by the EJB must be used.

      My application runs fine for a long time and then suddenly this error pops up and then all the following request fail with the same error. If Jboss is restart then it is working fine again.

      Can someone give me some pointer.

      Thanks in advance,
      Subramaniam V

      java.rmi.ServerException: EJBException:; nested exception is:
       javax.ejb.EJBException: Transaction not allowed
       at org.jboss.ejb.plugins.LogInterceptor.handleException(LogInterceptor.java:352)
       at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:125)
       at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.jav
      a:93)
       at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:613)
       at org.jboss.ejb.Container.invoke(Container.java:894)
       at sun.reflect.GeneratedMethodAccessor148.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:245)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
       at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:155)
       at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:104)
       at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:179)
       at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:165)
       at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
       at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:55)
       at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:169)
       at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:86)
       at $Proxy98.create(Unknown Source)
       at sun.reflect.GeneratedMethodAccessor322.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at org.jboss.net.axis.server.EJBProvider.makeNewServiceObject(EJBProvider.java:140)
       at org.jboss.axis.providers.java.JavaProvider.getNewServiceObject(JavaProvider.java:280)
       at org.jboss.axis.providers.java.JavaProvider.getServiceObject(JavaProvider.java:131)
       at org.jboss.axis.providers.java.JavaProvider.invoke(JavaProvider.java:335)
       at org.jboss.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:73)
       at org.jboss.axis.SimpleChain.doVisiting(SimpleChain.java:160)
       at org.jboss.axis.SimpleChain.invoke(SimpleChain.java:123)
       at org.jboss.axis.handlers.soap.SOAPService.invoke(SOAPService.java:560)
       at org.jboss.axis.server.AxisServer.invoke(AxisServer.java:355)
       at org.jboss.axis.transport.http.AxisServlet.doPost(AxisServlet.java:911)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
       at org.jboss.axis.transport.http.AxisServletBase.service(AxisServletBase.java:370)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252
      )
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:81)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202
      )
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:39)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:159)
      
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:59)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol
      .java:744)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
       at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
       at java.lang.Thread.run(Thread.java:534)
      


        • 1. Re: Transaction not allowed
          subramaniam.venkat

          Hello All,

          I found in the TxInterceptorCMT.java class in the method runWithTransactions
          we check for the oldTransaction and also check the transaction attribute.

          In my jbossjca-service.xml i have the SpecCompliant set to false,which means that jboss should not use the oldTransaction.

          If someone can tell me why the oldTransaction object is still maintained and how can i remove this. I am using Arjuna Transaction management.

          In my stateless SLSB i have the transaction attribute to NEVER.

          I am badly in need of support. Please please help me.

          Awaiting replies please,

          Thanks & Warm Regards,
          Subbu



          private Object runWithTransactions(Invocation invocation) throws Exception
           {
           // Old transaction is the transaction that comes with the MI
           Transaction oldTransaction = invocation.getTransaction();
           // New transaction is the new transaction this might start
           Transaction newTransaction = null;
          
           boolean trace = log.isTraceEnabled();
           if( trace )
           log.trace("Current transaction in MI is " + oldTransaction);
          
           InvocationType type = invocation.getType();
           byte transType = container.getBeanMetaData().getTransactionMethod(invocation.getMethod(), type);
          
           if ( trace )
           printMethod(invocation.getMethod(), transType);
          
           // Thread arriving must be clean (jboss doesn't set the thread
           // previously). However optimized calls come with associated
           // thread for example. We suspend the thread association here, and
           // resume in the finally block of the following try.
           Transaction threadTx = tm.suspend();
           if( trace )
           log.trace("Thread came in with tx " + threadTx);
           try
           {
           switch (transType)
           {
           case MetaData.TX_NOT_SUPPORTED:
           {
           // Do not set a transaction on the thread even if in MI, just run
           try
           {
           invocation.setTransaction(null);
           return invokeNext(invocation, false);
           }
           finally
           {
           invocation.setTransaction(oldTransaction);
           }
           }
           case MetaData.TX_REQUIRED:
           {
           int oldTimeout = 0;
           Transaction theTransaction = oldTransaction;
           if (oldTransaction == null)
           { // No tx running
           // Create tx
           oldTimeout = startTransaction(invocation);
          
           // get the tx
           newTransaction = tm.getTransaction();
           if( trace )
           log.trace("Starting new tx " + newTransaction);
          
           // Let the method invocation know
           invocation.setTransaction(newTransaction);
           theTransaction = newTransaction;
           }
           else
           {
           // We have a tx propagated
           // Associate it with the thread
           tm.resume(oldTransaction);
           }
          
           // Continue invocation
           try
           {
           Object result = invokeNext(invocation, oldTransaction != null);
           checkTransactionStatus(theTransaction, type);
           return result;
           }
           finally
           {
           if( trace )
           log.trace("TxInterceptorCMT: In finally");
          
           // Only do something if we started the transaction
           if (newTransaction != null)
           endTransaction(invocation, newTransaction, oldTransaction, oldTimeout);
           else
           tm.suspend();
           }
           }
           case MetaData.TX_SUPPORTS:
           {
           // Associate old transaction with the thread
           // Some TMs cannot resume a null transaction and will throw
           // an exception (e.g. Tyrex), so make sure it is not null
           if (oldTransaction != null)
           {
           tm.resume(oldTransaction);
           }
          
           try
           {
           Object result = invokeNext(invocation, oldTransaction != null);
           if (oldTransaction != null)
           checkTransactionStatus(oldTransaction, type);
           return result;
           }
           finally
           {
           tm.suspend();
           }
          
           // Even on error we don't do anything with the tx,
           // we didn't start it
           }
           case MetaData.TX_REQUIRES_NEW:
           {
           // Always begin a transaction
           int oldTimeout = startTransaction(invocation);
          
           // get it
           newTransaction = tm.getTransaction();
          
           // Set it on the method invocation
           invocation.setTransaction(newTransaction);
           // Continue invocation
           try
           {
           Object result = invokeNext(invocation, false);
           checkTransactionStatus(newTransaction, type);
           return result;
           }
           finally
           {
           // We started the transaction for sure so we commit or roll back
           endTransaction(invocation, newTransaction, oldTransaction, oldTimeout);
           }
           }
           case MetaData.TX_MANDATORY:
           {
           if (oldTransaction == null)
           {
           if (type == InvocationType.LOCAL ||
           type == InvocationType.LOCALHOME)
           {
           throw new TransactionRequiredLocalException(
           "Transaction Required");
           }
           else
           {
           throw new TransactionRequiredException(
           "Transaction Required");
           }
           }
          
           // Associate it with the thread
           tm.resume(oldTransaction);
           try
           {
           Object result = invokeNext(invocation, true);
           checkTransactionStatus(oldTransaction, type);
           return result;
           }
           finally
           {
           tm.suspend();
           }
           }
           case MetaData.TX_NEVER:
           {
           if (oldTransaction != null)
           {
           throw new EJBException("Transaction not allowed");
           }
           return invokeNext(invocation, false);
           }
           default:
           log.error("Unknown TX attribute "+transType+" for method"+invocation.getMethod());
           }
           }
           finally
           {
           // IN case we had a Tx associated with the thread reassociate
           if (threadTx != null)
           tm.resume(threadTx);
           }
          
           return null;
           }
          


          • 2. Re: Transaction not allowed
            weston.price

             


            In my jbossjca-service.xml i have the SpecCompliant set to false,which means that jboss should not use the oldTransaction.


            No. What this attribute means (and you are *strongly* encouraged not to use it) is that connection handles left open across requests will be reconnected on the next method invocation as opposed to being closed automatically if you do not do your own housekeeping.

            Again, this is almost always a bad idea to use.

            In regards to your transaction attribute, the NEVER designation means that if your component (ie EJB) is called in the context of a transaction you will receive an error which you can clearly see in the stack trace from your first post. So, something is starting a transaction and violating the tx attributes for your deployment.

            I can't tell exactly what problem you are having from your posts, but *something* along the way is initiating a transaction and thereby causing the error. It appears to be happening on an EJB home method which has probably not been annotated or correctly set up in your ejb-jar.xml file.





            • 3. Re: Transaction not allowed
              subramaniam.venkat

              Hello Weston,

              Thanks alot for your reply.
              I have attached my ejb-jar.xml below.

              From the SoapUser's bussiness method i have called some spring bean's where transaction is enabled ie the transaction attribute for that spring bean is Required.

              But as i don't want overall transaction for the SoapUser's bussiness method i have mentioned the transaction attribute as Never.

              Can you please tell me whether i have done anything wrong in the ejb-jar.xml.

              I am really very thankful to you for replying.

              Awaiting your response,

              Thanks & Warm Regards,
              Subbu

              <session>
               <display-name>SoapUser</display-name>
               <ejb-name>SoapUser</ejb-name>
               <home>
               com.SoapUserHome
               </home>
               <remote>
               com.SoapUser
               </remote>
               <ejb-class>
               com.UserEJB
               </ejb-class>
               <session-type>Stateless</session-type>
               <transaction-type>Container</transaction-type>
               <env-entry>
               <env-entry-name>ejb/BeanFactoryPath</env-entry-name>
               <env-entry-type>java.lang.String</env-entry-type>
               <env-entry-value>
               applicationContext.xml
               </env-entry-value>
               </env-entry>
               </session>
              <container-transaction>
               <method>
               <ejb-name>SoapUser</ejb-name>
               <method-name>*</method-name>
               </method>
               <trans-attribute>Never</trans-attribute>
               </container-transaction>
              


              • 4. Re: Transaction not allowed
                weston.price

                Your config looks reasonable enough. Being that this only happens rarely and after the application has been running for a long period of time, I would guess it's either a bug in JBoss, or with the way Axis is invoking the container; most likely the former.

                One question: the use of the NEVER transaction attribute is pretty restrictive for what (at least as far as I can tell) you are trying to do. A value of NOT_SUPPORTED might be a better bet simply because the EJB container will suspend any existing transaction context prior to executing the method on the EJB. This could be considered a *workaround* for your particular case and would avoid the exception.

                • 5. Re: Transaction not allowed
                  subramaniam.venkat

                  Hello Weston,

                  Thanks very much for the reply.

                  Do you want me to take any traces of the transaction management.

                  Thanks again,
                  Subbu.