Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > Develop EJB applications


Create timers using the EJB timer service for enterprise beans

We can use enterprise beans to take advantage of the EJB timer service to schedule time-based events.

New feature: In support of the EJB 3.1 specification, you can now create non-persistent EJB timers. This product also supports the expanded TimerService API for programmatic timer creation. In addition, you can configure the EJB container to automatically create a timer when the application starts.

WAS implements the EJB timer service. Based on your business needs, you can use persistent timers or non-persistent timers. Persistent timers are helpful if you are creating a timer for a time-based event that requires assurance of timer existence beyond the life cycle of the server. Previously started persistent timers automatically start when your server starts and persist through server shutdowns and restarts. For example, you can use persistent timers to start a system application or send a status notification on the expiration of a timer. Non-persistent timers are helpful in non-critical situations where the timer actions are skipped or redone without negative business impacts, such as polling a temperature.

We can create timers programmatically. We can also create timers automatically by using the @Schedule annotation in the bean class, or by using the timer element in the ejb-jar.xml deployment descriptor. By automatically creating timers, you can schedule a timer without relying on your enterprise bean invocation to programmatically start an EJB timer service creation method.

Persistent timers Persistent timers are implemented as a scheduler service task. By default, an internal or pre-configured scheduler instance is used to manage those tasks, and they persist in an Apache Derby database associated with the server process.

We can perform basic customizations to the internal scheduler instance. For information about customizing the scheduler instance, see the configuring a timer service information.

The creation and cancellation of Timers is transactional and persistent. If a Timer is created within a transaction and that transaction is later rolled back, the creation of the Timer is rolled back as well. Similar rules apply to the cancellation of a Timer. Previously started Timers are maintained across application server shutdowns and restarts.

Non-persistent timers

EJB 3.1 augments the EJB timer service to enable non-persistent EJB timers in addition to the persistent timers. Non-persistent timers have many of the same semantics and behavior as persistent timers, but without the overhead of a data store. Non-persistent timers have a different life cycle than persistent timers. Where persistent timers are maintained across application server shutdowns and restarts, non-persistent timers are active only while the application server is active. Unlike persistent timers, there are no commands to find or cancel non-persistent timers. Non-persistent timers are canceled when the application server is stopped or fails to remain in an active state.

As with persistent timers, the creation and cancellation of non-persistent timers is transactional. If a timer is created within a transaction and that transaction is later rolled back, the creation of the timer is rolled back as well. Similar rules apply to the cancellation of a timer.

We can configure non-persistent timers to share a thread pool with persistent timers, or to have a unique thread pool that is not shared with persistent timers.

Programmatically created timers A programmatically created persistent timer is maintained across application server shutdowns and restarts, unless it is canceled. It is the responsibility of application code or system administrator to delete a programmatically created timer which is no longer wanted.

To programmatically create a timer that is associated with your enterprise bean, the bean calls the getTimerService() method on the applicable context instance to get a reference to the TimerService object. The bean also calls one of the TimerService methods, such as createTimer, to specify the timer for the bean. This Timer instance is now associated with your bean. The TimerService methods are described in the EJB 3.1 specification. We can now pass the Timer instance to other Java code as a local object. After the Java code obtains the Timer instance, the code can use any of the methods defined by the javax.ejb.Timer interface, such as the cancel() or getTimeRemaining() methods.

In a clustered environment, a programmatically created persistent timer can run in any cluster member, but a programmatically created non-persistent timer runs only in the same JVM in which it was created.

Automatically created timers The EJB 3.1 specification augments the EJB timer service to enable the automatic creation of a timer when the application starts without relying on a bean invocation to programmatically start one of the timer service timer creation methods. Use the @Schedule annotation or the timeout-method deployment descriptor element to automatically create timers. Automatically created timers are created by the container as a result of application deployment.

The CancelEJBTimers command also cancels automatically created timers. When automatically created timers are canceled, the only way to recreate them is to uninstall the application and reinstall it again.

Timers in a clustered environment n a clustered environment, a persistent timer runs only in one cluster member which might not necessarily be the same cluster member it was created in. A non-persistent timer runs in each cluster member that it was created in - automatic non-persistent timers run in each cluster member that contains the EJB.

Automatic persistent timers are removed from their persistent store when their containing module or application is uninstalled. Therefore, do not update applications that use automatic persistent timers with the Rollout Update feature. Doing so uninstalls and reinstalls the application while the cluster is still operational, which might cause failure in the following cases:

  • If a timer running in another cluster member activates after the database entry is removed and before the database entry is recreated, then the timer fails. In this case, a com.ibm.websphere.scheduler.TaskPending exception is written to the First Failure Data Capture (FFDC), along with the SCHD0057W message, indicating that the task information in the database has been changed or canceled.

  • If the timer activates on a cluster member that has not been updated after the timer data in the database has been updated, then the timer might fail or cause other failures if the new timer information is not compatible with the old application code still running in the cluster member.

When you use the proxy server in the product, do not define a scheduler at the cell level if that scheduler is configured as the one to use for the EJB timer service. Doing so prevents persistent timers from running. This can happen if the proxy server gets the scheduler lease. Since no applications run in the proxy server, there is no application code to handle the timer events that are sent by the scheduler.

Retries and missed timeouts If you use EJB timers, understand the concepts of failure, retry, and missed timeouts.

  • A failure is a timeout execution that is attempted, but does not succeed.

  • A retry is an additional attempt to successfully execute a timeout that was previously attempted, but failed.

  • A missed execution is a timeout that must have been attempted, but was not, because the server was unavailable or busy retrying a previously failed timeout.

The retry behavior reflects:

  • Number of additional times that the server retries the failed timeout

  • Interval between these server retries

The missed timeout behavior reflects:

  • Whether the server eventually attempts missed timeouts, or not

  • If missed timeouts are eventually attempted, when those attempts occur

  • Interval between the missed timeout attempts


Retry and missed timeout behavior

Characteristic Default behavior Configurable
Number of retry attempts As many as it takes to succeed.

Persistent timers are temporarily deactivated if their scheduler failure threshold is reached in a server.

Yes, for non-persistent timers
Interval between retry attempts First retry attempt is immediate.

Subsequent retry attempts occur on the configured scheduler poll interval for persistent timers, and on the configured retry interval for non-persistent timers.

Yes
Missed timeout recovery All missed timeouts are recovered. No
When missed timeouts are recovered Both persistent and non-persistent timers recover missed timeouts when the blocking retry attempts stop. Additionally, persistent timers recover timeouts when an unavailable server restarts. No
Next timeout, after retry attempts are successful and missed timeouts are recovered At the next originally scheduled time. No

The configurable characteristics are configured on the scheduler instance for persistent timers and on the non-persistent timer configuration for non-persistent timers.

The following scenarios illustrate how the retry and missed timeout behavior influences the timeouts for both persistent and non-persistent timers.


Persistent timer scenario

A persistent timer is created and configured to run for the first time at 10:00 am, and then run every hour after that. The scheduler supporting the timer is configured with a 30 second poll interval.

The timer runs at 10:00 am and fails because a database is unavailable. The timer is immediately retried, and retried again every 30 seconds when the scheduler is polled, and keeps failing, until 12:30 pm. At that moment, a retry attempt succeeds because the database is now back online, and therefore the server stops retrying the previously failed attempt.

Now, the server begins to work through the missed timeouts. First, it attempts the timeout that must have run at 11:00 am, which succeeds at 12:31 pm. When the scheduler is polled again 30 seconds later, it attempts the timeout that must have run at 12:00 pm, which succeeds at 12:32 pm. The server is now current, and the next timeout occurs at its originally scheduled time of 1:00 pm, as opposed to an hour after the last success, which would have been 1:32 pm. Going forward, the original schedule is maintained. The schedule is not updated based on the time of the last successful timeout.


Non-persistent timer scenario

A non-persistent timer is created and configured to run for the first time at 10:00 am, and then run every hour after that. This non-persistent timer is configured to have a retry count of 5, and a retry interval of 30 minutes.

The timer runs at 10:00 am and fails because a database is not available. The timer is immediately retried, and fails again. Now, having executed the initial immediate retry, the server waits for the configured retry interval of 30 minutes between the next retry attempt. Retry attempts occur at 10:30 am and 11:00 am, and both fail. Finally, the fourth retry occurs at 11:30 am, and succeeds because the database is now back online.

Now, the server begins to work through the missed timeouts. The timeout that was originally scheduled for 11:00 am is immediately run, and succeeds at 11:31 am. The server is now current, and the next timeout occurs at its originally scheduled time of 12:00 pm (as opposed to an hour after the last success, which would be 12:32 pm).


Behavior of the getNextTimeout and getTimeRemaining methods

For both persistent and non-persistent timers, the Timer.getNextTimeout method returns a java.util.Date object that indicates the next time the timer is scheduled to execute. When you call the getNextTimeout method from a timeout callback method for an interval or calendar-based timer, the method returns the next scheduled time; for calendar-based timers with no future timeouts, the method throws the NoMoreTimeoutsException exception as required by the EJB 3.1 specification. When you call the getNextTimeout method from a timeout callback method for a single-action timer, the method returns the originally scheduled time. If a timeout callback method fails and retries are being attempted, the getNextTimeout method continues to return the originally scheduled time as if the failed execution had not occurred. In all cases, the Timer.getTimeRemaining method returns the difference in milliseconds between the getNextTimeout returned value and the current system time, which could result in a negative number, if the scheduled execution time was in the past.


Inheritance behavior of automatically created timers

Automatic timer methods in a hierarchy of bean classes cause multiple timers to be created. The number of timers associated with a timer method is not determined by the number of occurrences of the method in the source code. Instead, the number of timers associated with a timer method is determined by the number of beans with visibility to that method. For example:

@Stateless
public class Abean {

   @Schedule(hour=1)
   public void timerMethod1()

@Stateless
public class Bbean extends Abean {

   @Schedule(hour=2)
   public void timerMethod2()

@Stateless
public class Cbean extends Bbean {

   @Schedule(hour=2)
   public void timerMethod2()

In the previous bean class hierarchy, three automatic timers with callback method Abean.timerMethod1 are created, one for each bean instance with visibility to that method. One timer with callback method Bbean.timerMethod2 is created, and since that method is overridden by bean Cbean, only one timer with callback method Cbean.timerMethod2 is created.

In the previous example, when bean Abean is processed by the container, a single automatic timer is created, with callback method Abean.timerMethod1.

When the bean Bbean is processed by the container, an automatic timer is created with callback method Bbean.timerMethod2, and another automatic timer is created with callback method Abean.timerMethod1.

When the bean Cbean is processed by the container, an automatic timer is created with callback method CBean.timerMethod2. Another automatic timer is created with callback method Abean.timerMethod1. A timer for Bbean.timerMethod2 is not created when processing the bean Cbean. Bbean.timerMethod2 is not visible in the class hierarchy of Cbean because it is overridden by method Cbean.timerMethod2.

Consider another example like the previous one, if the @Stateless annotation were removed from classes Abean and Bbean, so that class Cbean is the only EJB. In that case, the only automatic timers created would be those visible to Cbean - one with callback method Abean.timerMethod1, one with callback method Cbean.timerMethod2.

Although beans can share identical code in an inherited bean callback method, the runtime behavior might be polymorphic. For example:

public class Employee {

   @Schedule(hour=1, dayOfMonth=-1, info = "payroll timer")
   public void getSalaryIncrease() {
      printChecks(salary * rate());

   protected float rate() {
      return (float)1.01;

}

public class Manager extends Employee {
   protected float rate() {
      return (float)1.15;
}

public class Executive extends Manager {
   protected float rate() {
      return (float)1.30;
}

In the previous example, each bean instance has an automatic timer with callback method getSalaryIncrease(). Although the same callback code is shared by each timer, note that the rate used in calculating the salary increase by each bean is different, due to polymorphism. That is, timer callback methods might be polymorphic in the same way that any Java methods might be.


Procedure


Attributes that control how dates are calculated

start Specifies a date value that is the inclusive starting point for calculating timeouts. The default value is null, which means the timer can start at any time.
end Specifies a date value that is the inclusive ending point for calculating timeouts. The default value is null, which means the timer continues to run indefinitely.
timezone Specifies a valid time zone according to the java.util.TimeZone API. The default value is null, which corresponds to the default time zone of the host server.

The second set of attributes determines when the timer runs. All attributes have a set of allowable values in addition to a special wild-card value *, which represents all possible values for that attribute.


Attributes that determine when the timer runs

second Specifies an integer in the range 0 to 59; default 0.
minute Specifies an integer in the range 0 to 59; default 0.
hour Specifies an integer in the range 0 to 23; default 0.
dayOfMonth Specifies an integer in the range 1 to 31; default *. Alternatively, the value can be:

  • The keyword Last, which corresponds to the last day of the month.

  • An integer in the range -1 to -7, which corresponds to a day before the last day of the month. For example, in a month with 31 days, the value -3 would correspond to the 28 day of the month.

  • The keyword 1st, 2nd, 3rd, 4th, 5th, or Last followed by a day of the week keyword Sun, Mon, Tue, Wed, Thu, Fri, or Sat. For example, you might use 3rd Sun and Last Wed. Use the abbreviated English ordinals and keywords.

dayOfWeek Specifies an integer in the range 0 to 7; default *. These values correspond to the keywords Sun, Mon, Tue, Wed, Thu, Fri, and Sat, which can be used instead. The values 0 and 7 both correspond to the keyword Sun. When both dayOfMonth and dayOfWeek are a value other than *, only one of the attributes needs to match a given day.
month Specifies an integer in the range 1 to 12; default *. These values correspond to the keywords Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, and Dec, which can be used instead.
year Specifies any four-digit calendar year; default *.

We can specify each of these attributes using an x-y range notation. For example, 0-3 is a valid range for the hour attribute and Jun-Aug is a valid range for the month attribute. Additionally, the second, minute, and hour attributes can be specified using an x/y increment notation. For example, 30/10 is a valid increment for the minute attribute, which includes the values 30, 40, and 50.

All attributes can also be specified as comma-delimited lists of single values or ranges of values. For example, the value 4,10-12 is valid for the hour attribute, and it corresponds to the times 4 AM, 10 AM, 11 AM, and 12 PM.

Use the America/New_York time zone value for its calendar operations. The timer runs on the last Friday of the months January, February, March, and June. On those days, it runs every two hours starting at 1:30 AM:

TimerService theTimerService = theEJBContext.getTimerService();
Timer theTimer = theTimerService.createCalendarTimer(new ScheduleExpression()
 .timezone("America/New_York")
 .month("Jan-Mar, Jun")
 .dayOfMonth("Last Fri")
 .hour("1/2")
 .minute(30))

  • To create timers automatically, define the timeout callback method using the @Schedule or @Schedules annotation or using the timer deployment descriptor element. Use annotations to write metadata for EJBs inside your source code. For more details, see the information about EJB 3.x metadata annotations.

    A bean can have multiple timeout callback methods for timers that are created automatically. The timeout callback method and automatic timers are identified by the @Schedule or @Schedules annotation in the source code or by using the timer deployment descriptor element in the ejb-jar.xml file. If you specify both annotations for the same method or if you specify an annotation and the timer deployment descriptor element for the same method, the metadata is combined and multiple automatic timers are created. The timeout callback methods must have a void return type and must accept either no parameters or a single parameter of type javax.ejb.Timer. All automatic timers are calendar-based.

    The server creates automatic timers when the application starts for the first time. Subsequent application start operations detect that timers have already been created for this application, and the timers are not recreated even if they were subsequently canceled. For persistent automatic timers, the server stores this data in the scheduler tables. If the application is installed on a server cluster, then configure the EJB container on each server to use a shared cluster-scoped scheduler. If the application is installed on independent servers, then you must ensure that each server is configured with a unique database or unique database table prefix.

    The application server automatically removes persistent automatic timers from the database when you uninstall the application while the server is running. If the application server is not running, manually delete the automatic timers from the database. Additionally, if you add, remove, or change the metadata for automatic timers while the server is not running, manually delete the automatic timers.

    • Define the automatic timer by using the @Schedule annotation. Use @Schedule annotation:
      class MyBeanImpl implements MyBean {
          @Schedule(hour="20", info="single timer", persistent=false)
          public void automatic(Timer t) {
              // ...
          }
      }
      

      The @Schedule annotation has second, minute, hour, dayOfMonth, dayOfWeek, month, year, and timezone elements that correspond to the same attributes of javax.ejb.ScheduleExpression. The annotation also has a persistent element that you can use to specify whether the server uses the EJB timer service scheduler to persist the timer. By default, automatic timers are persistent. Finally, the annotation also has an info element that you can use to specify application information that is delivered as a java.lang.String object with the javax.ejb.Timer object when the timeout callback method runs.

    • Define multiple automatic timers for the same method by using the @Schedules annotation. Use the @Schedules annotation:
      class MyBeanImpl implements MyBean {
          @Schedules(
              @Schedule(hour="1" info="1AM timer", persistent=false),         @Schedule(minute="0/30" info="30 minute timer")
          )
          public void automaticMultiple(Timer t) {
              // ...
          }
      }
      

    • Define timers using the deployment descriptor element. We can use the following subelements of the timer element:


      Subelements of the timer element

      Element Required or Optional Description
      schedule Required Includes optional second, minute, hour, day-of-month, day-of-week, month, and year subelements that correspond to the same attributes of javax.ejb.ScheduleExpression.
      start and end Optional Specify the inclusive starting and ending points for calculating timeouts.
      timeout-method Required Timeout callback method.
      persistent Optional Whether the server uses the EJB timer service scheduler to persist the timer. By default, automatic timers are persistent.
      timezone Optional Corresponds to the same attribute of javax.ejb.ScheduleExpression.
      info Optional Specifies application information that is delivered as a java.lang.String object with the javax.ejb.Timer object when the timeout callback method runs.

      Use the timer deployment descriptor element:

      <session>
      <ejb-name>MyBeanImpl
      </ejb-name>
      <timer>  
      <schedule>    
      <hour>20
      </hour>  
      </schedule>  
      <start>2000-01-01T13:00:00
      </start>  
      <timeout-method>    
      <method-name>automatic
      </method-name>  
      </timeout-method>  
      <persistent>false
      </persistent>  
      <timezone>America/New_York
      </timezone>  
      <info>single timer
      </info>
      </timer>
      </session>
      

  • Determine whether your timer is persistent or non-persistent.

    • Create a persistent timer.

    • Create a non-persistent timer.

  • Deploy your EJB application. After you deploy your EJB application, the enterprise bean must run so that the createTimer methods are called before the timer is created programmatically. If the timer is automatically created, the timer starts when the EJB application is started.


    Results

    You have programmatically or automatically configured an EJB timer that is either persistent or non-persistent.


    Related


    EJB metadata annotations
    Configure a timer service
    Deploy EJB modules
    Use schedulers
    Stop tasks that are failing
    Configure the timer service using scripting


    Related


    CancelEJBTimers command example
    Example: Using the Timer Service with the TimedObject interface
    EJB command group
    EJB timer service settings

    +

    Search Tips   |   Advanced Search