3 Replies Latest reply on Jan 30, 2007 12:16 PM by manik

    Concurrency problem

    kain1981

      Hi,

      I am using JBoss Cache in a cluster environment.
      From the different PCs within the cluster, the following code is called:

      1. get some X from the cache
      2. update X (for example, X++)
      3. put the updated X back to the cache
      4. return X to the client

      What I see is when this code is called repeatedly and simultenously from
      different PCs, the returned X is sometimes the same as the one on
      another PC!

      The code is being called from a stateless session bean. Playing with
      TransactionAttribute I sometimes got org.jboss.cache.lock.UpgradeException,
      sometimes the situation described above.

      Here is some of the cache settings:

      <attribute name="TransactionManagerLookupClass">org.jboss.cache.JBossTransactionManagerLookup</attribute>
      <attribute name="IsolationLevel">SERIALIZABLE</attribute>
      <attribute name="NodeLockingScheme">PESSIMISTIC</attribute>
      <attribute name="CacheMode">REPL_SYNC</attribute>
      


      How should I achieve data integrity using TreeCache?

        • 1. Re: Concurrency problem
          manik

          JBC does not acquite cluster-wide locks. These are only done when a tx is committing.

          Try this:

          
          boolean doSomething()
          {
           int X = -1;
           while (X == -1)
           {
           try
           {
           X = getX();
           }
           catch (RollbackException e)
           {
           X = -1;
           }
           }
           return X;
          }
          
          int getX()
          {
           // start a new tx here.
           Integer X = (Integer) cache.get(fqn, key);
           X++;
           cache.put(fqn, key, X);
           // commit tx here.
           return X;
          }
          
          


          • 2. Re: Concurrency problem
            kain1981

            Thanks a lot for the explanation!

            What if I implement getX() as a stateless session bean method? Can I use container
            transaction in here instead of declare them programatically (tx.commit() etc)?
            If yes, what transaction attribute should be used?

            Another question is - can I tune somehow this method to make automatically
            all this stuff with while, try and catch? I think it's not good to write it
            every time I need interacting with the cache. Maybe you can advise something.

            Thanks!

            • 3. Re: Concurrency problem
              manik

              Retrying on tx failure needs to be on a case by case basis. Not all cache operations *should* be retried on tx failure. It depends on your app.

              Yes, you can use your app server's transaction attribs. REQUIRES_NEW to create the tx, but you will have to commit it yourself.