Single Threaded Stateless Session Beans?

Discussions

EJB design: Single Threaded Stateless Session Beans?

  1. Single Threaded Stateless Session Beans? (11 messages)

    Something that has bothered me for a long time about stateless session beans is that I could never understand why they are single threaded. The only way that they make sense to me is if they are multi-threaded.
    For example, let's say I have a session bean that runs a search on a database. I would have a method that takes in some search criteria, grabs a DB connection out of the pool, runs a select, and then returns the connection to the pool and the data to the client. All of these would make the most sense as local variables, so why would I ever want to have multiple instances of this stateless session bean?
    Can anyone think of any example where multiple single threaded stateless session beans make more sense than a single instance of a multithreaded SLSB?
  2. Paul

    The SLSBs are single threaded because a TX Context, Principal is associated with bean instance when it is called. These beans are pooled and unless the max pool size is reached are processed in separate threads ( Vendor dependent).

    If SLSBs were designed thread safe every call would have looked like a servlet doGet/Post with request info containing Tx Context , Security Context info and etc. So at least the code looks clean (developer dependent).

    Mike
  3. Couldn't the TX Context and Principal be associated with the thread instead of with the bean instance? I would think you would have associate the TX with the thread when you call another EJB anyway. That way the next EJB has access to TX and security information.
    Developer code could still get access to the UserTransaction and Principal objects through the EJBContext. The server would just look up these objects based on the current thread instead of based on the EJB instance.

    Paul
  4. This would force Vendors to run your app server using JDK 1.4 for reasonably fast ThreadLocal performance. But it would be very Nice.
  5. I will have to read up a little on ThreadLocal variables to get a better understanding of them.
    I was thinking you could just associate an id (Thread name?) with each Thread in the server thread pool, and use this id to store whatever user specific stuff you wanted to store.
    Code in the EJBContext object could then do something like this:
    Principal user = userPrincipalTable.get(Thread.currentThread().getName());

    Assuming that the thread was given a unique name when it was created by the server. Access to the userPrincipalTable object would need to be synchronized also.
    Would calling the getName() method be slow pre JDK 1.4?
  6. I don't think the reason for this design decision was the problem of associating transaction contexts with threads. This is not such a big problem, certainly not beyond the capabilities of modern App servers.
    You don't need JDK1.4 to achieve fast ThreadLocals if you have control over the types (i.e Java class) of threads running in your system. In that case you can implement your own ThreadLocals. App server vendors do have that control. All they have to do is put transaction context reference in the base class of their threads. This allows better speed than even JDK1.4 ThreadLocals can offer.

    I can think of two reasons why a sinlge-threaded model was chosen for SLSBs:

    1. Caching non-reusable resources such as sockets, specific Java libraries (XML parsers, XSLT templates, stuff like that), and pre-configured JCA connections (for instance you might want to prepare some statements for use throughout the lifetime of the session bean).

    2. Make SLSBs and SFSBs as similar as possible.

    You might argue that the second reason I listed shouldn't really be a goal. But I think it does add some clarity to the spec, ensuring you don't ever have to worry about threads.

    Gal
  7. 1. Caching non-reusable resources such as sockets, specific Java libraries (XML parsers, XSLT templates, stuff like that), and pre-configured JCA connections (for instance you might want to prepare some statements for use throughout the lifetime of the session bean).

    >

    I think you are correct that the spec designers probably had this in mind. Although I don't think it is the best design choice. Consider a SLSB that has a method that will perform several tasks involving non-reusable resources. If each of these resources are instance variables within one single threaded SLSB, they will all be locked until the method is complete, which is not very effeficient way to use them. If you separate them into several EJBs called from one controller (Facade?), then there is really no reason to make the facade single threaded. Maybe the EJB spec designers should have defined a generic resource pool (like the one in jakarta commons), that could be used if a resource needed to be single threaded.


    > 2. Make SLSBs and SFSBs as similar as possible.
    >

    I don't think this really takes any confusion out of the spec. In fact I would argue that the names of the beans are somewhat misleading. Probably Service Beans (with option for single or multithread) would have been a better name for Stateless Session Beans. And stateful session beans should have been removed altogether, but that is for another discussion.
  8. Interesting question, here is one reason:

    SessionContext object passed to SLSB at the time of creating the bean using setSessionContext() method is typically stored in an instance variable. This object provides to SLSB the information about run-time environment, information about the calling Principal etc. Using the SessionContext object, you can get caller information using getCallerPrincipal() method. As Callerid is unique to each client, you should have one SLSB per client, hence one thread per bean instance.

    Eager to hear other comments.

    -Balaji.
  9. Don't they achieve the same goal, using multithreaded singleton SLSB or multiple instances of single-threaded SLSB's? I would say the latter is much easier to implement by the container vendor. Are you worried about the overhead of object instantiation? You can prepopulate the bean instance pool so the performance penalty is minimal at runtime. Are you worried about memory usage? I doubt in a real world situation multiple instances of SLSB will consume that much more memory.

    Isn't this similar to servlet, where theoretically you should have a single instance that allows multiple threads to access it, but many web container vendors opt to create multiple instances of the same servlet to handle simultaneous calls?
  10. Don't they achieve the same goal, using multithreaded singleton SLSB or multiple

    > instances of single-threaded SLSB's? I would say the latter is much easier to
    > implement by the container vendor.

    Yes, they do achieve the same goal. And for the reasons you mentioned, the single SLSB seems slightly better. You don't have the extra overhead of instance initialization, the server code is a little simpler, and you have a smaller section of synchronized code.


    > Isn't this similar to servlet, where theoretically you should have a single
    > instance that allows multiple threads to access it, but many web container
    > vendors opt to create multiple instances of the same servlet to handle
    > simultaneous calls?

    Yes, servlets do have a single instance that is multithreaded. The only time that a web container might create multiple instances of a servlet is if the servlet implements the SingleThreadModel.
  11. ..., the server code is a little simpler, and you have a smaller section of synchronized code.


    Simpler? How? I would say it is more complex because a SLSB developer has to worry about doing thread synchronization. The whole philosophy of the EJB specs are that developers should never worry about writing plumbing code, such as thread synchronization in business logic.

    > The only time that a web container might create multiple instances of a servlet is if the servlet implements the SingleThreadModel.

    If the web container can do that, why shouldn't EJB container do the same, i.e, using multiple single-threaded SLSB's to handle simultaneous client invocations?
  12. ..., the server code is a little simpler, and you have a smaller section of synchronized code.


    >
    > Simpler? How? I would say it is more complex because a SLSB developer has to worry about doing thread synchronization. The whole philosophy of the EJB specs are that developers should never worry about writing plumbing code, such as thread synchronization in business logic.
    >

    Sorry, I meant the application server code would be simpler, not the EJB code. The EJB developers would not need to worry about thread synchronization if there is a generic resource pool available. This is how JDBC connections are handled. The J2EE blueprints even says that you shouldn't save a JDBC connection as an instance variable. Instead you should get and release the connection within the scope of a single method. In my opinion, other pooled resources should be handled that way instead of keeping instance variables and pooling the beans.


    > > The only time that a web container might create multiple instances of a servlet is if the servlet implements the SingleThreadModel.

    >
    > If the web container can do that, why shouldn't EJB container do the same, i.e, using multiple single-threaded SLSB's to handle simultaneous client invocations?

    In my experience, the SingleThreadModel interface is rarely used in web applications because of the same reasons discussed here. I don't see why the same doesn't apply to stateless session beans. SLSBs should at least give the option of being multi-threaded.