Container - SessionBean Contract

What are the specifics regarding timeouts of Stateful Sessions?

The EJBPassivationTimeout option specifies the time between “sweeps” for stateful sessions to be passivated to secondary storage. All session beans not currently associated with a transaction are marked for passivation. The value is in seconds. The default value is 5 seconds.

To disable passivation set the env. var. EJBPassivationTimeout to zero, as in:

% vbj -DEJBPassivationTimeout=0 com.inprise.ejb.Container ...

The container passivates EVERY [-DEJBPassivationTimeout=x] x seconds all instances not currently in a transaction - so the passivation is not synchronized with the last usage of the bean. Session bean passivation is geared towards putting limits on resource usage rather than keeping the persistent storage and the beans cached data always in synch.

There is a separate timeout for the session instance - the amount of time the bean lives in secondary storage before being blown away altogether. To specify a timeout interval for removal of stateful session beans you need to put an XML element in the vendor specific part of the deployment descriptor. (cart example has an illustration)

Consider, as an example, a shopping cart with a session timeout of 60 seconds and a passivation timeout of 10 seconds. Every ten seconds, shopping carts not currently involved in a transaction are written to secondary storage. After 60 seconds of inactivity the shopping cart is blown away.

If a stateful session bean is in a transaction, then it cannot timeout. So if a transaction is running for too long (maybe hung) then will the sessions ever be pasivated?

It depends whether the transaction is being coordinated by the builtin JTS or ITS. The lightweight transaction engine that ships with the Container does not support transaction timeouts. Thus, once you start a transaction and use a session bean, that bean will not be passivated (or timeout) until the transaction completes.

ITS does support transaction timeouts. There is a way to set the system default timeout, and a global maximum timeout. You will have to consult the ITS docs for details. Thus, using ITS, session beans will timeout after the user transaction times out (t1), then after the session bean passivates (t2), and then after the session bean times out (t3). So an unused session bean, in an idle transaction, will be removed after no more than t1 + t2 + t3 seconds

What happens if I end up making concurrent calls to a session bean?

You may get this exception log starting like:
>>>> EJB LOG >>>>
Failure in StateTransitionManager
com.inprise.ejb.StateTransitionException: Cannot invoke "afterBegin" on a bean in
state: TX_READY
It is not legal for multiple clients to use a stateful session bean. They are single user objects (or at least, non-parallel access objects). Furthermore, the EJB spec says that a container does not have to detect invalid multiple accesses to a stateful session bean, since in the general case, this is not possible.

Are the Container statistics object counters wrong?

Scenario:

I have a stateful session bean. I invoke some business method on the bean ... look at the server and it shows (after 5 seconds) "PASSIVE 1, Total in Memory 1". My client sleeps for 5 seconds and invokes the same business method. The server reports, "PASSIVE 2, Total In Memory 2", strange? Each time I call the method, the EJB Container’s counters are bumped. Is this correct? I expected there would be only one instance because I am working on the same one object.

Explanation

In fact the number of created objects do NOT increase., the objects are being Activated and Passivated. This may account for one thinking that the "counters are out" when the objects are being Activated and Passivated.

There are two places where a session bean is created:
1) when newInstance is called on the class (transitioning out of the "does not exist" state).
2) when readObject is called on the object serialization stream (when transitioning out of the "passive" state)

Note that a new object is created in both cases. However, in the second case, the object's constructor is not called. Thus, there are two places where an object is created, but only one place where it is constructed.

Now just because the container releases the instance, does not mean that the VM garbage collects the instance. We distinguish these counts by "total in memory" (how many are in memory, including both ones that we have references to, and ones that we don't), and "total in use" which is only the count of the number of beans we are hanging on to. It is up to the garbage collector to reduce the "total in memory" down to the "total in use" at its discretion. Basically the GC typically only fires when the VM gets low on memory, so for mostly idle clients, not very often.

There is still a bug in the counters whereby the PASSIVE count is not reliable. You should ignore this counter.

I am trying to understand the mechanism of creating and destroying for stateless beans
1- in the specs: the container can invoke the instance creation at any time not realted to a client calling the create method: how is this decided by the container?
2- when the container no longer needs the instance it destroys it. How does the container decide that it doesn't need the instance?
3- what is the capacity of poolings?

Currently the Container has a rather simple approach to stateless session beans. It creates as many session beans as are needed to support every concurrent use. So, if three clients simultaneously call a session bean, three instances will be used. Stateless beans do not have a timeout in EJB. Thus, they will never actually be removed. They will remain in a pool to be ready to serve future requests on the bean.

Note that in practice one needs one thread per access to an EJB object, so one will run out of memory for threads long before one will run out of memory for beans, so we believe not bounding or compacting the pool is not a serious problem.