13 Replies Latest reply on Jul 5, 2013 2:43 AM by blabno

    Seam Transaction illegal state

    zeeman

      Hi all,


      I'm using AS7 7.1.CR1b, Seam 3.1 Final. Postgres and latest JDBC driver.


      I use seam faces and I have the transaction interceptor enabled. While I debug the app in Eclipse, I get the below exception. It seems like the transaction times out, but it also kills AS7 (gets hung) and the app stops working. Is this a bug in seam transaction? Or do I need to handle this exception? In either case what do you recommend to deal with this? I also Have infinispan span enabled as Hibernate 2nd level cache.


      Error:


      javax.enterprise.event.ObserverException
              sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
              sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
              sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
              java.lang.reflect.Constructor.newInstance(Constructor.java:513)
              java.lang.Class.newInstance0(Class.java:355)
              java.lang.Class.newInstance(Class.java:308)
              org.jboss.weld.util.reflection.SecureReflections$16.work(SecureReflections.java:343)
              org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
              org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInstantiation(SecureReflectionAccess.java:173)
              org.jboss.weld.util.reflection.SecureReflections.newInstance(SecureReflections.java:340)
              org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:33)
              org.jboss.weld.injection.Exceptions.rethrowException(Exceptions.java:73)
              org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:162)
              org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:241)
              org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:229)
              org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:207)
              org.jboss.weld.manager.BeanManagerImpl.notifyObservers(BeanManagerImpl.java:569)
              org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:564)
              org.jboss.weld.event.EventImpl.fire(EventImpl.java:68)
              org.jboss.seam.transaction.TransactionServletListener.requestInitialized(TransactionServletListener.java:117)
              org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
              org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
              org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897)
              org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626)
              org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2033)
              java.lang.Thread.run(Thread.java:662)
      root cause
      
      javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!
              com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:65)
              org.jboss.seam.transaction.UTTransaction.begin(UTTransaction.java:51)
              org.jboss.seam.transaction.DefaultSeamTransaction.begin(DefaultSeamTransaction.java:88)
              org.jboss.seam.transaction.TransactionServletListener.requestInitialized(TransactionServletListener.java:110)
              org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
              org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
              org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897)
              org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626)
              org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2033)
              java.lang.Thread.run(Thread.java:662)
      root cause
      
      java.lang.IllegalStateException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!
              com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.checkTransactionState(BaseTransaction.java:259)
              com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.begin(BaseTransaction.java:61)
              org.jboss.seam.transaction.UTTransaction.begin(UTTransaction.java:51)
              org.jboss.seam.transaction.DefaultSeamTransaction.begin(DefaultSeamTransaction.java:88)
              org.jboss.seam.transaction.TransactionServletListener.requestInitialized(TransactionServletListener.java:110)
              org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
              org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
              org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:897)
              org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:626)
              org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:2033)
              java.lang.Thread.run(Thread.java:662)
      



      Persistence.xml: I have two objects (Property and Action) that I need to evict manually via jmx from the cache. Otherwise, they shall be cached live forever.


      <persistence-unit name="myProject-PU" transaction-type="JTA">
                      <description>myProject Persistence Unit</description>
                      <provider>org.hibernate.ejb.HibernatePersistence</provider>
                      <jta-data-source>java:jboss/datasources/PostgresDS</jta-data-source>
                      <exclude-unlisted-classes>false</exclude-unlisted-classes>
                      <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
                      <properties>
                              <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
                              <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <!-- create-drop -->
                              <property name="hibernate.jdbc.batch_size" value="0" />
                              <property name="hibernate.show_sql" value="false" />
                              <property name="hibernate.id.new_generator_mappings" value="true" />
                              <property name="hibernate.generate_statistics" value="false" />
                              
                              <property name="hibernate.cache.use_query_cache" value="true" />
                              <property name="hibernate.cache.use_second_level_cache" value="true"/>
                              <property name="hibernate.cache.infinispan.use_synchronization"  value="false"/>
                              <property name="hibernate.cache.infinispan.statistics" value="true"/>
                              <property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/hibernate" />
                              
                              <property name="hibernate.cache.infinispan.com.myProject.model.Action.eviction.strategy" value= "NONE"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Action.eviction.wake_up_interval" value= "1000000"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Action.eviction.max_entries" value= "300"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Action.expiration.lifespan" value= "1000000000"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Action.expiration.max_idle" value= "1000000000"/>
                              
                              <property name="hibernate.cache.infinispan.com.myProject.model.Property.eviction.strategy" value= "NONE"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Property.eviction.wake_up_interval" value= "1000000"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Property.eviction.max_entries" value= "300"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Property.expiration.lifespan" value= "1000000000"/>
                              <property name="hibernate.cache.infinispan.com.myProject.model.Property.expiration.max_idle" value= "1000000000"/>
                                                      
                              <!-- <property name="hibernate.transaction.flush_before_completion" value="true"/> -->
                              
                              <!-- use a file system based index in prod -->
                              <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.impl.FSDirectoryProvider" />
                              <property name="hibernate.search.default.indexBase" value="myProjectindexes" /> 
      <!--                         <property name="hibernate.search.default.directory_provider" value="ram" /> -->
                                                      
                              <property name="hibernate.search.lucene_version" value="LUCENE_34" />
                              <property name="hibernate.search.default.exclusive_index_use" value="true" />
                              <property name="hibernate.search.analyzer" value="org.apache.lucene.analysis.standard.StandardAnalyzer"/>
                              <property name="hibernate.search.worker.execution" value="async"/>
                              <property name="hibernate.search.worker.thread_pool.size" value="1"/>
                              <property name="hibernate.search.worker.buffer_queue.max" value="100"/>
                      </properties>
              </persistence-unit>
      



        • 1. Re: Seam Transaction illegal state
          langerc

          I have exact the sam exception, but without infinispan. The exception occours after a transaction timeout. After this timeout or error (db connection failure, ..) nothing is working anymore because of the "is already associated with a transaction"

           

          I dont need transactions in my project, can i disable them somehow?

           

          My problem right now is that this error showed up out of nothing, if my project has an error once the whole zone is dead until restartet from scrach.

          • 3. Re: Seam Transaction illegal state
            zeeman

            Does this mean I should disable the transaction listener in web.xml and manually annotate my classes Transactional?

             

            If I keep default behaviour of Seam transaction (enabled) how can I control transactions? (roll them back, commit them, roll back a transaction on timeout)?

             

            Looks like the request transaction listener has a bug, it should roll back/end transactions that have timed out. No?

            • 4. Re: Seam Transaction illegal state
              lightguard

              Disabling the listener and manually annotating the classes / methods would be one way of doing it sure.  If a transaction is marked for rollback, then the listener will roll it back. You could of course inject the @Default SeamTransaction and roll it back as well.   As for timeout, not really sure, never came across that one. I guess it depends on what the status of the transaction is when it times out.  Take a look at https://github.com/seam/transaction/blob/develop/impl/src/main/java/org/jboss/seam/transaction/TransactionServletListener.java or debug it and see if there's something that isn't covered during a timeout, or something that is incorrect.

              • 5. Re: Seam Transaction illegal state
                zeeman

                Thanks Jason.

                 

                I looked at the code in TransactionServletListener.java and from the stack trace I posted, it looks like the issue is starting a transaction without checking if there is one associated already with the current thread that's in a different status than active.

                 

                Another possible issue, what happens if requestDestroyed for a request never gets called? Does the transaction associated with the request stay open? As far as I know the app server uses a thread pool to process requests, if a thread already has a transaction registered with it there will be a an issue starting a new transaction with that thread. See java comment below:

                 

                if (this.tx.getStatus() == Status.STATUS_ACTIVE) {

                                this.log.warn("Transaction was already started before the listener");

                            } else {

                                this.log.debugf("Beginning transaction for request %s", sre.getServletRequest());

                                // should a tx be started only if the current status is not STATUS_ACTIVE? Do we need more checks or clean up here?

                                this.tx.begin();

                            }

                 

                 

                Finally, from as7 7.1CRb standalone.xml, is 300 ms from bold line below the default transaction timeout?

                 

                        <subsystem xmlns="urn:jboss:domain:transactions:1.1">

                            <core-environment>

                                <process-id>

                                    <uuid/>

                                </process-id>

                            </core-environment>

                            <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>

                            <coordinator-environment default-timeout="300"/>

                        </subsystem>


                • 6. Re: Seam Transaction illegal state
                  lightguard

                  If you're coming in with a thread that already has a transaction, something is wrong (or perhaps the server is switching threads?).  I can't think of a reason why requestDestroyed wouldn't be called. If you have an instance where it isn't we can discuss that.  As for the xml stanza, I really don't know.

                  • 7. Re: Seam Transaction illegal state
                    lukascz

                    Did anyone solve this issue? I'm facing the same problem after we deployed our applications; many

                      javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - ARJUNA016051: thread is already associated with a transaction!

                    are being thrown. I use Seam 3.1 Transaction module

                    • 8. Re: Seam Transaction illegal state
                      lukascz

                      So I spent some time on debugging and it turns out that sometimes the thread tries to begin transaction that was already rolled back. Thus, in TransactionServletListener.requestInitialized() the transaction status is 4 (rolled back).

                       

                      Do you know what might be side effects if I do not begin transaction if it was rolled back (and let the request continue in processing)?

                       

                      Is there a way how to create new transaction when I found out that the current one associated with the thread was rolled back? Now the transaction is injected by:

                      @Inject

                      @DefaultTransaction

                      private SeamTransaction tx;

                      But I do not know how to create new instance of it (if possible).

                       

                      Thanks,

                      Lukas

                      • 9. Re: Seam Transaction illegal state
                        blabno

                        Jason,

                         

                        I'm facing same exception. The reason why requestDestroyed is not called is because the request hasn't finished. Guess why! We've added RichFaces push. Push works in a way that client (i.e. Atmosphere) opens connection (request) and keeps it open.

                        Tommorrow I'll see what can be done about that, but first guess is that TransactionServletListener should be turned off and substituted with something configurable solution to exclude some paths.

                        • 10. Re: Seam Transaction illegal state
                          lightguard

                          Ouch.

                           

                          IIRC, I did add a way to effectively disable the listener, though I don't recall right now what it was. There we go, (https://github.com/seam/transaction/blob/develop/impl/src/main/java/org/jboss/seam/transaction/TransactionServletListener.java) it's a context initialization param.

                          • 11. Re: Seam Transaction illegal state
                            nathandennis

                            Bernard, Saw this come through the alerts. Please post your findings to this one. After looking over this thread,, I'm pretty sure I'm about to get into the same situation with Richfaces push. any information will be greatly appreciated.

                            • 12. Re: Seam Transaction illegal state
                              ahmedza

                              Hi,

                               

                              I am facing the same issue in a web application. We have processes and forms in Guvnor repository in a package. Guvnor is configured with JackRabbit and Oracle 11. Our web application accesses the process definitions and forms from guvnor. This issue gets fixed on restart of server. But, once this issue occurs, application can't access any asset or process definition from Guvnor using rest APIs. Even the Guvnor web-interface starts giving error. Only 4 users are using the application and getting this transaction association error.

                               

                              Following is the environment for the jboss instance where guvnor is configured.

                               

                              1. drools-guvnor-5.5.0-Final
                              2. JBOSS ASS 7.1.0

                              3. Oracle 11

                               

                              Does this listener disabling works. I have also disabled the listener and waiting for the results.

                              • 13. Re: Seam Transaction illegal state
                                blabno