9 Replies Latest reply on Oct 12, 2007 5:07 PM by matt.drees

    conceptual question about concurrency

    matt.drees

      Maybe this questions stems from the fact that I haven't buckled down and bought an EJB3 book yet (I do mostly pojo work with Seam). But, it also relates to application-scoped pojos, so I want to understand.

      The reference documentation makes it clear you can have a stateless bean that uses injected variables. But it also mentions that stateless beans can be accessed concurrently. So, what prevents the injected variables from being overwritten by injection from another concurrent thread?

      I.e, what keeps the following scenario from happening?

      @Stateless
      @Name("bean")
      public class Bean {
      
       @In EntityManager entityManager;
      
       @In Long id;
      
       public void doStuff() {
       ...
       //(a)
       entityManager.find(Entity.class, id);
       //(b)
       }
      
      }
      


      1. Thread A calls doStuff()
      2. Seam interceptor sets entityManager and id
      3. Thread A gets to point (a)
      4. Thread A pauses
      5. Thread B calls doStuff()
      6. Seam interceptor sets entityManager and id (different values than thread A)
      7. Thread B gets to point (b)
      8. Thread B pauses
      9. Thread A wakes up
      10. Thread A executes the find() with the wrong entityManager and the wrong id

      The same question applies to application-scoped components.

      Thanks

        • 1. Re: conceptual question about concurrency
          wschwendt

           

          But it also mentions that stateless beans can be accessed concurrently. So, what prevents the injected variables from being overwritten by injection from another concurrent thread?


          The EJB container ensures this. Session Beans are NOT multithreaded, neither stateless session beans (SLSBs) nor stateful session beans.

          If you have two threads referencing a stateless session bean (in your example the threads A and B), both threads operate on a different bean instance. Therefore it cannot happen that the interceptor for thread B overwrites the injections for thread A.



          • 2. Re: conceptual question about concurrency
            matt.drees

            Thanks for answering!

            So, now I have two questions.

            1.
            Is Seam's reference documentation incorrect when it says "The EJB container allows stateless components to be accessed concurrently, and throws an exception if multiple threads access a stateful session bean"? It's hard for me to see how stateless session beans can be both single-threaded and able "to be accessed concurrently."

            2.
            Does Seam similarly ensure that application-scope pojos are not multi-threaded?

            • 3. Re: conceptual question about concurrency

              1: Maybe the documentation is a bit unclear there. If you access stateless components concurrently, the container will supply enough instances from the pool so that each thread will get its own instance.

              To put this another way: From a threads perspective the connection between a component name and a certain bean instance is lost. The name of the stateless compoennt might be resolved to a different been instance next time.

              2: Don't know.

              Regards

              Felix

              • 4. Re: conceptual question about concurrency
                pmuir

                1) It doesn't mean anything to access a SLSB to be accessed concurrently - an SLSB holds no state outside of the method you are calling. Yes, you can have fields, but they might have data from previous uses of the bean, or none.

                • 5. Re: conceptual question about concurrency
                  wschwendt

                   

                  "matt.drees" wrote:
                  Thanks for answering!

                  So, now I have two questions.

                  1.
                  Is Seam's reference documentation incorrect when it says "The EJB container allows stateless components to be accessed concurrently, and throws an exception if multiple threads access a stateful session bean"? It's hard for me to see how stateless session beans can be both single-threaded and able "to be accessed concurrently."


                  The answer is that EJB _instances_ are never accessed directly. This holds true even if local business interfaces rather than remote interfaces are used. Even then a client never accesses an EJB _instance_ directly. Instead, when a client references an EJB bean, it actually references a proxy object provided by the EJB container. Thus, the EJB container can intercept calls to this proxy object and dispatch incoming calls to different bean instances as needed, in order to ensure that only a single thread operates on a bean instance.

                  In the case of a stateless session bean (SLSB), the bean instance does not hold any conversational state. Therefore, the EJB container typically maintains a pool of SLSB instances, and on receipt of an incoming call to a proxy object, it selects an instance out of this pool to which it routes the call. When there are concurrent incoming calls to a proxy object, the container can thus dispatch these calls to different bean instances. Each bean instance sees only a serialized sequence of method calls.

                  As for stateful session beans (SFSB), they do hold conversation state, often they are referred to as an "extension of the client". SFSBs conceptually execute on behalf of single client. They are not meant to be shared by more than one client at the same time. This implies they cannot be called by the same client using multiple threads. Clients are not allowed to make concurrent calls to a stateful session object. If a client-invoked business method is in progress on a bean instance when another client-invoked call, from the same or different client, arrives at the same instance of a stateful session bean class, the container may throw the java.rmi.RemoteException to the second client, if the client is a remote client, or the javax.ejb.EJBException if the client is a local client. This restriction does not apply to a stateless session bean because the container routes each request to a different instance of the session bean class.



                  • 6. Re: conceptual question about concurrency
                    wschwendt

                     

                    "matt.drees" wrote:
                    Thanks for answering!
                    2.
                    Does Seam similarly ensure that application-scope pojos are not multi-threaded?


                    The Seam reference manual, section "Concurrency model" in chapter "3: The conceptual component model" contains information about it.

                    From what I understand based on the aforementioned section:

                    session scope: Seam serializes requests to Session scoped JavaBeans (POJOs) and Session Beans by default.

                    application scope: serialization of requests is not the default behavior, although it could be enforced on any JavaBean or Session Bean component by adding the @Synchronized annotation




                    • 7. Re: conceptual question about concurrency
                      matt.drees

                      Thanks for all of your responses (especially wschwendt; I appreciate your detail).

                      I understand why injection is safe for stateless components now. I'm not convinced injection is safe for (non-@Synchronized) application-scope components; when I get some free time I'll test it out and report what I find.

                      • 8. Re: conceptual question about concurrency
                        pmuir

                        I updated the docs to reflect his and the FAQ of resue of SLSBs from the pool

                        • 9. Re: conceptual question about concurrency
                          matt.drees

                          Thanks Pete