5 Replies Latest reply on Feb 4, 2004 6:05 PM by belaban

    distributed transactions with jboss-cache

    kstogian

      Hello,

      i have a cluster [jboss3.2.3, tomcat5.0.16, treecache cvs] of 2 computers running jboss treecache with the configuration:
      TransactionManagerLookupClass=org.jboss.cache.JBossTransactionManagerLookup,
      CacheMode=REPL_SYNC.

      Reading and writing to the cache outside the transaction context of a stateless ejb is working fine [objects put in cache are replicated to all nodes].
      When i try to write within a user transaction i get:
      From the node that executes the request:
      18:36:11,924 INFO [STDOUT] java.lang.IllegalStateException: No transaction.
      18:36:11,924 INFO [STDOUT] at org.jboss.tm.TxManager.rollback(TxManager.jav
      a:272)
      18:36:11,924 INFO [STDOUT] at org.jboss.ejb.EnterpriseContext$UserTransacti
      onImpl.rollback(EnterpriseContext.java:492)

      From the other node:
      18:36:11,940 ERROR [TreeCache] rollback(): entry for transaction <kle:7800>:7 not found

      Any ideas of what might be wrong or how you got it right?
      Thanks Kleandros.

        • 1. Re: distributed transactions with jboss-cache

          Hi,

          Would you mind to post your code snippet so it is easier to debug?

          Thanks,

          -Ben

          • 2. Re: distributed transactions with jboss-cache
            kstogian

            The class below [short version] is extended by our app ejbs; Cache is an interface to cache implementations like jboss tree cache; its instantiated in a ServiceMBean and accessed via jndi lookup. Hope this is what you mean with snippet

            import javax.ejb.*;
            import javax.transaction.*;
            import javax.naming.*;
            import org.jboss.cache.*;
            public class FlowController implements SessionBean {
             private SessionContext sessionContext = null;
            
             public FlowController() {
             }
             public void setSessionContext(SessionContext sc) {
             this.sessionContext = sc;
             }
             public void process(Object businessComponent) throws Exception {
             UserTransaction utx = sessionContext.getUserTransaction();
             try {
             utx.begin();
             InitialContext ctx = new InitialContext();
             if (ctx != null) {
             Object ctxMap = ctx.lookup("Cache");
             if ((ctxMap != null) && (ctxMap instanceof Cache)) {
             ((Cache) ctxMap).put("/data", "key", businessComponent, null);
             }
             }
             utx.commit();
             }
             catch (Exception e) {
             utx.rollback();
             }
             }
             public void ejbActivate() throws EJBException,RemoteException {
             }
             public void ejbPassivate() throws EJBException,RemoteException {
             }
             public void ejbRemove() throws EJBException,RemoteException {
             }
            }
            


            • 3. Re: distributed transactions with jboss-cache
              belaban

              I fixed this. The code is in TreeCache.java in the CVS,

              Bela

              • 4. Re: distributed transactions with jboss-cache

                I have also re-activated a MBeanUnitTestCase junit test under jboss-head for UserTransaction and distributed transaction runs under JBoss. You can check it out under testsuite/src/main/org/jboss/test/cache/test/local

                Ben

                • 5. Re: distributed transactions with jboss-cache
                  belaban

                  Here's my SFSB code. Method incrCounterWithUserTx() is defined as UNSUPPORTED wrt tx support in ejb-jar.xml.

                  This works for me with both LOCAL, REPL_ASYNC and REPL_SYNC cache modes. Although I found another bug with REPL_SYNC, which I'm working on now.

                  public int incrCounterWithUserTransaction() {
                  Integer counter=null;
                  UserTransaction tx=null;

                  try {
                  // tx=ctx.getUserTransaction();
                  tx=(UserTransaction)new InitialContext().lookup("UserTransaction");
                  tx.begin();

                  counter=(Integer)cache.get("/bela/ban", "counter");
                  if(counter == null) {
                  counter=new Integer(0);
                  }
                  else {
                  counter=new Integer(counter.intValue() +1);
                  }
                  cache.put("/bela/ban", "counter", counter);
                  tx.commit();
                  }
                  catch(Exception e) {
                  e.printStackTrace();
                  try {
                  if(tx != null)
                  tx.rollback();
                  }
                  catch(SystemException e1) {
                  e1.printStackTrace();
                  }
                  }

                  return counter != null? counter.intValue() : -1;
                  }