Entity
beans set
timers on a specific type of entity bean (e.g., Ship, Customer,
Reservation, etc.) with a specific primary key. When a timer goes
off, the container uses the primary key associated with the timer to
load the entity bean with proper data. Once the entity bean is in the
ready state—its data is loaded and it’s ready
to service requests—the ejbTimeout( )
method
is invoked. The container associates the primary key with the timer
implicitly.
Using timers with entity beans allows entity beans to manage their own timed events. As we’ve seen, it makes sense for a Ship to manage its own maintenance schedule. The maintenance schedule is unique for each ship and required in order to keep the ship sailing, so it could be considered intrinsic to the definition of a ship. If, however, the timed event is not a part of the entity’s definition, it’s best to put the timer into a taskflow bean (i.e., stateless session or message-driven) that represents the scenario, instead of placing the logic in the entity bean. This avoids entity bloat , in which an entity bean’s definition becomes huge from attempting to manage every possible application of the entity bean. It’s the same reason we move taskflow logic out of entity beans and into session beans.
A serious concern with entity beans is the possibility of timer attack , which occurs when too many timers expire at the same time. A timer attack is not caused by malicious intent, but rather poor design. For example, if all the Customer beans in Titan system had timers set to expire five days before a cruise (perhaps to send email reminders to customers), it’s possible that thousands of timers would expire simultaneously. This scenario could lead to a timer attack. A timer attack causes congestion and competition for resources that can overwhelm the EJB server to the point where it cannot handle other requests. The timer attack can be exacerbated by timer rollbacks, which occur when a timer fails to execute properly. As timers fight for resources and fail, they are re-executed, prolonging the strain on the system. Good design and intelligent containers are the only safeguard against a timer attack. Be aware of the types of timers you are creating and the possibility of many timers executing simultaneously.
The entity bean can access the TimerService
from
the EntityContext
in any business method or
callback method, except the seEntityContext( )
method. The timers associated with an entity bean are canceled
automatically when the entity is removed, so there is no need to
explicitly cancel timers in the ejbRemove( )
method.
When an entity bean implements the TimedObject
interface, its life cycle changes to accommodate timed events. When a
bean’s timer expires, the container transitions a
bean instance to the Ready state, calling its ejbActivate( )
and then ejbLoad( )
methods after
loading the bean’s persistent fields. When the
ejbTimeout( )
method returns, the container calls
the bean’s ejbStore( )
method,
stores changes to the database, calls the bean’s
ejbPassivate( )
method, and returns the bean to
the Pooled state. Figure 13-1 shows the life cycle
of the entity bean that implements the TimedObject
interface.