3 Replies Latest reply on Jul 29, 2013 9:04 AM by popoctavian

    JBoss 6.1.0.Final SFSB concurrency issue

    popoctavian

      Hi,

       

      I am trying to run a test to investigate a performace issue after upgrading from JBoss 4.0.5 to 6.1. For this I use a simple test application with a service which starts threads, each thread looks-up a SFSB instace and execute a method to increment a number.

      From this test I notticed that SFSB method calls in the multi-threaded test are serialized - one execution after the other. Investigating in more detail I found that this serialization is caused by CMC interceptor from server/current/deploy/ejb3-interceptors-aop.xml.

      If I commented out CMC, performance increased significantly.

       

      Is this a known behavior?

      What are the implications if I comment CMC?

       

      Thanks.

       

      Below are code snippets from test:

       

       

      @Service
      public class TestingService
      {
      
          public static int numberOfThreads=2;
      
          public static void start() throws Exception
          {
      
              startTest(numberOfThreads);
          }
      
          public static void startTest(int threadNumber) throws InterruptedException
          {
              Thread [] threads = new Thread[threadNumber];
      
              for (int i=0;i< threadNumber;i++)
              {
                  Thread t = new Thread()
                  {
                      public void run()
                      {
                          Client testClient = new Client();
                          testClient.processNumber(Math.round(Math.random()*1000));
                          testClient.destroy();
                      }
                  };
                  t.start();
                  threads[i] = t;
              }
      
              for(int i=0; i<threadNumber; i++)
              {
                  threads[i].join();
              }
          }
      }
      
      public class Client
      {
          IGenericSFB genericSFB;
      
          public Client()
          {
              genericSFB = (IGenericSFB) ServiceLocator.getLocalService(GenericSFB.class.getSimpleName());
              System.out.println("This address " + genericSFB + " " + genericSFB.hashCode());
          }
      
      
          public void processNumber(Long number)
          {
              System.out.println("Client - Start incrementing " + number);
              genericSFB.incrementNumber(number);
              System.out.println("Client - Finish incrementing " + number);
      
          }
      ...
      
      
      @Stateful
      public class GenericSFB implements IGenericSFB, Serializable
      {
          private int number;
          private String stuff;
          private String someOtherStuff;
      
          public Long incrementNumber(Long number)
          {
              System.out.println("SFB - start incrementing number " + number + " by " + this);
              try
              {
                  Thread.currentThread().sleep(10000);
              }
              catch (InterruptedException e){}
      
              System.out.println("SFB - finish incrementing number " + number);
      
              return 0L;
          }
      ...
      
      
      
        • 1. Re: JBoss 6.1.0.Final SFSB concurrency issue
          jaikiran

          Is this JBoss EAP 6.1.0.Final (based on AS7) or the community JBoss AS 6.1.0.Final?

          • 2. Re: JBoss 6.1.0.Final SFSB concurrency issue
            popoctavian

            It is the community JBoss AS 6.1.0.Final.

            • 3. Re: JBoss 6.1.0.Final SFSB concurrency issue
              popoctavian

              No one experienced this?

               

              Below I posted the ContainerManagedConcurrencyInterceptor implementation which is invoked when a method from statefull beans is invoked.

               

              public Object invoke(Invocation invocation) throws Throwable
                  {
                      Lock lock = getLock(invocation);
                      long time = DEFAULT_MAX_TIMEOUT_VALUE;
                      TimeUnit unit = DEFAULT_MAX_TIMEOUT_UNIT;
                      AccessTimeoutEffigy timeout = getAccessTimeout((MethodInvocation) invocation);
              
              
                      if (timeout != null)
                      {
                          if (timeout.getTimeout() < 0)
                          {
                              // for any negative value of timeout, we just default to max timeout val and max timeout unit.
                              // violation of spec! But we don't want to wait indefinitely.
                              logger.debug("Ignoring a negative @AccessTimeout value: " + timeout.getTimeout() + " and timeout unit: "
                                      + timeout.getUnit().name() + ". Will default to timeout value: " + DEFAULT_MAX_TIMEOUT_VALUE
                                      + " and timeout unit: " + DEFAULT_MAX_TIMEOUT_UNIT.name());
                          }
                          else
                          {
                              time = timeout.getTimeout();
                              unit = timeout.getUnit();
                          }
                      }
                      boolean success = lock.tryLock(time, unit);
                      if (!success)
                      {
                          throw new ConcurrentAccessTimeoutException("EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on " + invocation
                                  + " - could not obtain lock within " + time + unit.name());
                      }
                      try
                      {
                          return invocation.invokeNext();
                      }
                      finally
                      {
                          lock.unlock();
                      }
                  }
              

               

              The invocations on incrementNumber from GenericSFB are serialized at boolean success = lock.tryLock(time, unit);

              It does not make sens to have mutual exclusion for statefull beans invocatins, as it looks to be implemented.