2 Replies Latest reply on Mar 17, 2009 1:51 PM by angusm

    org.jboss.cache.GlobalTransaction never released

    morisona

      I am using the PojoCache with JBoss Cache 1.4.1SP12 and JBoss AS 4.0.5.
      GlobalTransaction is never released, and eventually the system runs out of memory.
      After some profiling and tracing it seems they are held by org.jboss.cache.interceptors.CacheStoreInterceptor in the Maps preparingTxs and m_txStores. They should be released when the invoke method is called with a Commit Method. But this never happens.
      I have a test case for this.
      I think my -service.xml and code are fairly standard. I give them below.
      Any hints or suggestions or explanations would be more than welcome.

      <?xml version="1.0" encoding="UTF-8"?>
      <!-- ===================================================================== -->
      <!-- -->
      <!-- Sample PojoCache Service Configuration -->
      <!-- -->
      <!-- ===================================================================== -->
      <server>
      
       <!-- Used inside JBoss AS -->
       <classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar"/>
      
       <!-- ==================================================================== -->
       <!-- Defines configuration -->
       <!-- ==================================================================== -->
      
       <mbean code="org.jboss.cache.aop.PojoCache" name="jboss.cache:service=TestCache">
      
       <!-- Used inside JBoss AS -->
       <depends>jboss:service=Naming</depends>
       <depends>jboss:service=TransactionManager</depends>
      
      
      
      
      
       <attribute name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
      
       <!--
       Configure the TransactionManager
       Note: having no TransactionManager configured results in this log msg:
       WARN [org.jboss.cache.TreeCache] method _lock() should not be invoked on TreeCache
      
       -->
       <!--
       Node locking scheme:
       OPTIMISTIC
       PESSIMISTIC (default)
       -->
       <attribute name="NodeLockingScheme">PESSIMISTIC</attribute>
      
       <!--
       Note that this attribute is IGNORED if your NodeLockingScheme above is OPTIMISTIC.
      
       Isolation level : SERIALIZABLE
       REPEATABLE_READ (default)
       READ_COMMITTED
       READ_UNCOMMITTED
       NONE
       -->
       <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
      
       <!--
       Valid modes are LOCAL
       REPL_ASYNC
       REPL_SYNC
       INVALIDATION_ASYNC
       INVALIDATION_SYNC
       -->
       <attribute name="CacheMode">LOCAL</attribute>
      
       <!--
       Just used for async repl: use a replication queue
       -->
       <attribute name="UseReplQueue">false</attribute>
      
       <!--
       Replication interval for replication queue (in ms)
       -->
       <attribute name="ReplQueueInterval">0</attribute>
      
       <!--
       Max number of elements which trigger replication
       -->
       <attribute name="ReplQueueMaxElements">0</attribute>
      
       <!-- Name of cluster. Needs to be the same for all clusters, in order
       to find each other
       -->
       <attribute name="ClusterName">testcluster</attribute>
      
       <!-- JGroups protocol stack properties. Can also be a URL,
       e.g. file:/home/bela/default.xml
       <attribute name="ClusterProperties"></attribute>
       -->
      
       <attribute name="ClusterConfig">
       <config>
       <!-- UDP: if you have a multihomed machine,
       set the bind_addr attribute to the appropriate NIC IP address -->
       <!-- UDP: On Windows machines, because of the media sense feature
       being broken with multicast (even after disabling media sense)
       set the loopback attribute to true -->
       <UDP mcast_addr="228.1.2.5" mcast_port="45577" ip_ttl="64" ip_mcast="true" mcast_send_buf_size="150000" mcast_recv_buf_size="80000" ucast_send_buf_size="150000" ucast_recv_buf_size="80000" loopback="false"/>
       <PING timeout="2000" num_initial_members="3" up_thread="false" down_thread="false"/>
       <MERGE2 min_interval="10000" max_interval="20000"/>
       <FD shun="true" up_thread="true" down_thread="true"/>
       <VERIFY_SUSPECT timeout="1500" up_thread="false" down_thread="false"/>
       <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" up_thread="false" down_thread="false"/>
       <pbcast.STABLE desired_avg_gossip="20000" up_thread="false" down_thread="false"/>
       <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10" down_thread="false"/>
       <FRAG frag_size="8192" down_thread="false" up_thread="false"/>
       <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true"/>
       <pbcast.STATE_TRANSFER up_thread="false" down_thread="false"/>
       </config>
       </attribute>
      
      
       <!--
       The max amount of time (in milliseconds) we wait until the
       initial state (ie. the contents of the cache) are retrieved from
       existing members in a clustered environment
       -->
       <attribute name="InitialStateRetrievalTimeout">60000</attribute>
      
       <!--
       Number of milliseconds to wait until all responses for a
       synchronous call have been received.
       -->
       <attribute name="SyncReplTimeout">15000</attribute>
      
       <!-- Max number of milliseconds to wait for a lock acquisition -->
       <attribute name="LockAcquisitionTimeout">1000</attribute>
      
       <!--
       <attribute name="EvictionPolicyClass"></attribute>
       -->
      
       <!-- Name of the eviction policy class. We have commented it off to disable eviction.
       -->
      
      
       <attribute name="UseRegionBasedMarshalling">true</attribute>
       <!--<attribute name="InactiveOnStartup">true</attribute>-->
      
       </mbean>
      
      
      
      </server>
      
      


      UserTransaction userTrans = null;
       try {
       InitialContext ctx = new InitialContext();
       Object objtr = ctx.lookup("UserTransaction");
       if (objtr==null)
       throw new ServletException("No 'UserTransaction' found in JNDI");
       userTrans = (UserTransaction)objtr;
       userTrans.begin();
      
       if (operation.equals("create")) {
       Toto toto = new Toto(nick, name);
       System.out.println("new totos classloader is:" + toto.getClass().getClassLoader());
       cache.putObject("/totos/" + nick, toto);
      
       } else if (operation.equals("update")) {
       Object obj = cache.getObject("/totos/" + nick);
      
       if (obj == null) {
       System.out.println("nulll");
       pw.println("/totos/" + nick + " not found<br/>");
       } else {
      
       System.out.println("Object retrieved from cache class is: " + obj.getClass().getName() + ", Classloader is:" + obj.getClass().getClassLoader());
       System.out.println("Context Classloader is:" + Thread.currentThread().getContextClassLoader());
       System.out.println("Class loader of a new class is:" + new Toto().getClass().getClassLoader());
       Toto toto = (toast.Toto) obj;
       toto.setName(name);
       }
      
       } else if (operation.equals("delete")) {
       cache.removeObject("/totos/" + nick);
      
       } else
       throw new ServletException("Unknown operation: " + operation);
      
       userTrans.commit();
       } catch (Exception e) {
       try {
       userTrans.rollback();
       } catch (Exception e1) {
       // TODO Auto-generated catch block
       e1.printStackTrace();
       }
       throw new ServletException(e);
       } finally {
       userTrans = null;
       }