The EJB timer service is a new feature added to the EJB architecture in the EJB 2.1 specification. This feature can be used with both BMP and CMP entity beans, as well as with stateless session beans and message-driven beans. In Section 8.2, Parts Developed by Wombat, on page 249, we provide an example that illustrates use of the timer service with entity beans. Business applications generally need a way to perform actions at specific times for example, preparing a summary report of each day's transactions at the end of every business day or after a certain interval of time for example, if an acknowledgment for a business operation is not received in a certain time frame, alert an administrator. The EJB timer service can be used to provide such notifications to enterprise beans at a specific time or after specific time intervals. Notifications can be provided either once or on a recurring basis after a specified interval. The EJB timer service is intended to be used for coarse-grained hours, days, or longer notifications that are usually needed for business processes. It is not designed to be accurate for fine-grained milliseconds, seconds time periods or for any kind of real-time processing. 7.3.1 Timer InterfacesTo set up a timer notification, an enterprise bean uses the EJB container's timer service to create a Timer object. The timer service is accessed using the EJBContext.getTimerService method. Code Example 7.14 shows the timer-related interfaces TimerService, Timer, TimerHandle, and TimedObject: Code Example 7.14 Timer Interfacespublic interface TimerService { public Timer createTimer(long duration, Serializable info) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, javax.ejb.EJBException; public Timer createTimer(long initialDuration, long intervalDuration, Serializable info) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, javax.ejb.EJBException; public Timer createTimer(Date expiration, Serializable info) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, javax.ejb.EJBException; public Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, javax.ejb.EJBException; public Collection getTimers() throws java.lang.IllegalStateException, javax.ejb.EJBException; } public interface Timer { public void cancel() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; public long getTimeRemaining() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; public Date getNextTimeout() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; public Serializable getInfo() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; public TimerHandle getHandle() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; } public interface TimerHandle extends Serializable { public Timer getTimer() throws java.lang.IllegalStateException, javax.ejb.NoSuchObjectLocalException, javax.ejb.EJBException; } public interface TimedObject { public void ejbTimeout(Timer timer); } EJB application code uses the createTimer methods of TimerService to create Timer objects. There are four such methods:
A bean can create multiple timer objects. The bean can associate an information object with each timer object to help the bean differentiate between multiple timer objects. When a timer expires, the container sends a notification to the bean that created the timer, by calling the timer's ejbTimeout method and providing the timer as an argument. This requires that all beans that create timers must implement the TimedObject interface. Timer objects implement the Timer interface; which provides methods to cancel delete the timer; get the time remaining before the timer expires; get the time when the timer will expire; get the information object associated with the timer; and get the timer's TimerHandle object. A bean can get a reference to a Timer object in one of three ways:
The TimerHandle object provides a serializable handle to a Timer object. A bean can store this handle in a database or other persistent storage and later retrieve it. Entity beans using container-managed persistence may store the TimerHandle object in a CMP field. 7.3.2 Timers, Persistence, and TransactionsTimer objects are persistent objects managed by the container. This means that a timer object survives crashes of the container or process in which the enterprise bean created the timer. Typically, a container implementation would store timer objects in a database or other persistent storage, so the timer's notifications could be delivered and so the timer object could be accessed even after a container restart. For entity beans, a timer object is associated with the bean instance identified by a primary key that created the timer. Thus, when a container process restarts after a crash, the container first activates an instance of that entity bean with the primary key and then, if there are any outstanding expired timer notifications for the bean, delivers these timer notifications to the bean by calling its ejbTimeout method. If an entity bean instance is removed, all timers associated with that bean instance are also removed. Because there is no identity associated with instances of stateless session beans and message-driven beans, to deliver the timer notification, the container uses any bean instance of the same type as the stateless session or message-driven bean that created the timer. Timer objects are also transactional objects. This means that timer creation, removal, and expiration typically happen within the context of a transaction. If that transaction rolls back, the timer operation is also rolled back. This results in the following semantics of timers and transactions:
|