3 Replies Latest reply on Jan 17, 2006 2:44 PM by Marek Gmyrek

    Caching behavior in EJB container

    Ben Wang Master

      Ok, this is currently related to SFSB case that is reported from the customer. Basically, here is the problem description:

      Basically, in SFSB, if you configure the max pool size to 2, but I have more than 2 threads accessing the SFSB container, there can be a problem. Let?s say bean1 and bean2 have been created. When another thread trying to create bean3, it will have to passivate bean2 first. But during the passivation stage, in AbstractInstaceCache.tryToPassivate(), it will try to obtain the lock by calling lock2.attemptSync(). Problem is during this period, another thread have been accessing bean2 and therefore obtain the lock already.

      As a result, tryToPassivate() would fail and report ?unable to passivate? error. Still, it will remove the cache entry from the map (this is a bug, IMO). So next time around, activation would fail because it never get passivated.

      I am think that we should block, i.e., lock2.attempt(secs) instead. However, there can be another problem as Scott's comment below indicates.

      If we don't block, option is to throw exception to the thread that is creating bean3. But this can happen frequently is bean pool size is small and it is highly concurrent.

        • 1. Re: Caching behavior in EJB container
          Ben Wang Master

          Scott's follow up comment:

          A bean with an active method cannot be passivated and the reason we do not obtain the lock is described in a comment right before the attemptSync call about a deadlock problem. Not passivating is not a huge deal in general as it should only result in a transient excess of beans. The removal of the bean from the cache is a problem.

          To block the call, the deacklock problem would have to be revisted to validate what is going on. There is a user forum post saying that we are creating sfsb instances that end up being thrown away if the session is activated so we may need to revisit the cache behavior. We could also have a notion of lazy passiviation that would result in marking the bean as would have been passivated so that it can be passivated after the current call ends. One potential problem with this is that time based passivation that fails to passivate an active instance should simply fail as its a race condition between the background timer and active usage. We should discuss the issues in the forums as I'm sure Bill has other cache implementations in ejb3 that need to be validated as well.

          • 2. Re: Caching behavior in EJB container
            Ben Wang Master

            OK, I am proposing to simply allow the cache size to grow without passivating it temporarily then. I have created a Jira issue for that:
            http://jira.jboss.com/jira/browse/JBAS-2668

            • 3. Re: Caching behavior in EJB container
              Marek Gmyrek Newbie

               

              "ben.wang@jboss.com" wrote:
              Scott's follow up comment:

              To block the call, the deacklock problem would have to be revisted to validate what is going on. There is a user forum post saying that we are creating sfsb instances that end up being thrown away if the session is activated so we may need to revisit the cache behavior. We could also have a notion of lazy passiviation that would result in marking the bean as would have been passivated so that it can be passivated after the current call ends. One potential problem with this is that time based passivation that fails to passivate an active instance should simply fail as its a race condition between the background timer and active usage. We should discuss the issues in the forums as I'm sure Bill has other cache implementations in ejb3 that need to be validated as well.


              I played a bit with SFSB cache. I created a cache with max size 2 and created several SFSB (but not concurrently) to see how they are passivated/activated. Below the sequence of client calls and container actions:

              1. client create
               -> new instance 1
               -> set session context 1
               -> create 1
              2. client create
               -> new instance 2
               -> set session context 2
               -> create 2
              3. client create
               -> new instance 3
               -> set session context 3
               -> create 3
               -> passivate instance 1
              4. client create
               -> new SFSB instance 4
               -> set session context 4
               -> create 4
               -> passivate instance 2
              5. client calls business method on bean 1
               -> new instance 5
               -> set session context 5
               -> set session context 1
               -> activate 1
               -> passivate 3
               -> business method on 1
              


              So, bean instance 5 is created but never used ie. calling a business method on a passivated bean causes creation of a new bean instance for nothing.

              Regards,
              Marek.