Statelessness

Discussions

EJB programming & troubleshooting: Statelessness

  1. Statelessness (9 messages)

    Say I hold a reference to a given instance of a stateless EJB.

    EJB.call1();
    EJB.call2();

    Are the 2 calls guaranteed to go to the same instance?

    Thanks...

    Threaded Messages (9)

  2. Statelessness[ Go to top ]

    No.

    The container can implement a caching strategy for Stateless Session Beans at its discretion.

    From Section 6.3 of the EJB 1.1 Spec:

    To help the container manage its state, a session bean is specified at deployment as having one of the following state management modes:
    • STATELESS—the session bean instances contain no conversational state between methods; any instance can be used for any client.

    The last statement, 'any instance can be used for any client' is the key here.



  3. Statelessness[ Go to top ]

    [1] and [2] seem contradictory...

    EJB 2.0 Section 7.8

    [1]
    Stateless session beans are session beans whose instances have no conversational state. This means that
    all bean instances are equivalent when they are not involved in servicing a client-invoked method.

    The term “stateless” signifies that an instance has no state for a specific client. However, the instance
    variables of the instance can contain the state across client-invoked method calls. Examples of such
    states include an open database connection and an object reference to an EJB object.

    ...

    [2]
    Because all instances of a stateless session bean are equivalent, the container can choose to delegate a
    client-invoked method to any available instance. This means, for example, that the Container may dele-gate
    the requests from the same client within the same transaction to different instances, and that the
    Container may interleave requests from multiple transactions to the same instance.
  4. Statelessness[ Go to top ]

    The statements aren't contradictory at all, although they may seem kind of confusing at first, especially since [1] lists an an example something which in practice should be discouraged. A stateless session bean really should not maintain an open database connection between method calls; the connection should be obtained from a datasource (the reference to which can be safely cached and held in an instance variable) at the begining of a method call and returned to the pool at the end of the method.

    The caching of a datasource reference, however, is a good example of how a stateless session bean can contain instance variable state across method calls. For instance, a stateless session method which needs to make a database connection can perform a JNDI lookup on the appropriate DataSource, store the reference in an instance variable, then retrieve and use the connection, returning it to the pool when the method completes. The next time the method is executed (by the same or a different client), the DataSource instance variable will already be initialized (not null), so the method can just use it to retrieve a connection, elminating the overhead of another JNDI lookup. This state, however, is localized to the bean-- the client knows nothing about it and does not depend on the bean being initialized in any way.

    Hope this helps,
    Tim Perrigo
  5. Statelessness[ Go to top ]

    Don't disagree with your interpretation and approach, but I think you are reading into the spec too much.

    [1] clearly discourages nothing.
    [1] also clearly says that the instance variable is a state and the data connection is just an example.
    [1] does not say I cannot keep a value in an instance variable across method calls from the same client.

    My conclusion is that [1] and [2] are indeed contradictory and [2] is what people assume to be right.

    The spec should be updated...
  6. Statelessness[ Go to top ]

    The spec is the theory, your app server is the reality. Fire up your favorite app server and run a test. Let this guide your choices.
  7. Statelessness[ Go to top ]

    While I agree that the spec could be more clear on this, the key to understanding it on these points is to recognize the difference between "conversational state" and what could be referred to as "bean state" (the values of the beans instance variables). Conversational state is state specific to a client/session object pair (see section 7.1 of the EJB2.0 pfd 2 spec). Stateless session beans, by definition (the first part of statement [1]) cannot have conversational state-- the client cannot assume that the values of the instance variables of a stateless session bean will be maintained across method calls. This lack of conversational state makes it possible (as Toby's post pointed out earlier) for the container to implement a caching strategy for stateless session beans. This is made explicit in statement [2], which is not a contradiction but a refinement of the definition put forward in statement [1].

    However (as illustrated by the second part of statement [1]), just because the session bean cannot be counted on to hold client-specific information, this does not mean that the instance variables of a bean cannot hold state useful to the bean instance itself, as my earlier example of the caching of a datasource illustrates. The difference is that this state is not conversational-- it is not associated in any way with the client which invoked the method; it is simply (in this case) used by the bean to optimize its performance in servicing requests (for any client).

    Does this clear things up at all?

    Tim
  8. Statelessness[ Go to top ]

    That's how I read it as well...there is instance state and conversational state. Stateless beans do indeed have an 'instance state'...so you can set some values for the lifetime of the bean itself.

    This means that you can in your ejbCreate() have code that insatiates a datasource or other resource. The caveat being that this resource is global to all instances of the bean.

    It may help to think of a Stateless Session bean as a type of Singleton - it can have state but this state is the same regardless of who uses the Bean. This is good because the container can then optimise the calls and create a pool of bean instances that are guaranteed to be the same.
  9. Statelessness[ Go to top ]

    Yeah, I am of the same understanding, that the instance state makes the bean a kind of a singleton or makes the state a kind of "static class variable"

    However, this "static class variable" value depends on the a given instance and is not constant across all instances. Ie. EJB-Instance-1 sets the data source, EJB-Instance-2 could still have the data source reference being null. And so, the instance state depends on whether a client call was delegated to EJB-Instance-1 or EJB-Instance-2.
  10. Statelessness[ Go to top ]

    <quote>
    Yeah, I am of the same understanding, that the instance state makes the bean a kind of a singleton or makes the state a kind of "static class variable"

    However, this "static class variable" value depends on the a given instance and is not constant across all instances. Ie. EJB-Instance-1 sets the data source, EJB-Instance-2 could still have the data source reference being null. And so, the instance state depends on whether a client call was delegated to EJB-Instance-1 or EJB-Instance-2.
    </quote>

    That's precisely the point with SLSB.

    1) Your client cannot and must not assume the state within the bean is the same as the last call.

    2) Also, your bean must not assume that the client has pre-initialized anything (which is a logical follow on from the
    first statement.)

    You can be sure that the server will only run one thread through the bean at a time, so you can safely check database connections and initialize them within the bean if you need to. But the point made earlier is very correct. You should always (aka a finally{} block) tidy up things of this nature when you're done with them.

    HTH

    Chz

    Tony