Configuration options for persistent enterprise JavaBeans timers

Persistent EJB timers do not require any configuration other than enabling the ejbPersistentTimer feature and setting up the default data source to point to a database. However, optional configuration settings are available to customize alternative data source selection, failover enablement, missed timer action, database polling, and task retries.

EJB timer configuration is specified by an optional timerService configuration element. Configuration attributes for persistent EJB timers are further grouped under a persistentExecutor element configuration. By default, the EJB timer service uses a persistent executor instance named defaultEJBPersistentTimerExecutor. You can customize the EJB persistent timer configuration by configuring the timer service to use a different persistent executor instance. However, the best practice for customizing the EJB persistent timer configuration is to override the defaultEJBPersistentTimerExecutor instance so that you inherit default values from the defaultEJBPersistentTimerExecutor instance.

For example, the following configuration overrides the retry limit but inherits the other default settings:
 <persistentExecutor id="defaultEJBPersistentTimerExecutor" retryLimit="50"/>
Customizing the database store for persistent timer tasks
Persistent EJB timer tasks are persisted to a database. Configuration related to the database is grouped under the databaseStore configuration element. Unless configured otherwise, an instance of databaseStore named defaultDatabaseStore is used for persistent EJB timers and by other product features that require a database. An example of overriding the defaultDatabaseStore instance,
 <databaseStore id="defaultDatabaseStore" dataSourceRef="DB2DataSource" tablePrefix="MYTIMERS"/>
An example of configuring the defaultEJBPersistentTimerExecutor instance to use a different databaseStore instance,
  <persistentExecutor id="defaultEJBPersistentTimerExecutor" taskStoreRef="MyDBStore"/>
  <databaseStore id="MyDBStore" dataSourceRef="DB2DataSource" tablePrefix="MYTIMERS">
    <authData user="user1" password="password1"/>
Enabling failover

Failover is configured by specifying a missed task threshold, beyond which a timer is considered missed and is eligible to be run by another server. A server that runs a timer reserves the timer for the duration specified by the missedTaskThreshold attribute. If the time elapses without a successful run of the timer, another server can try to run the timer for the same interval, after which, if it has not run successfully, the timer is available to be run by another server. This cycle continues until a server is able to successfully run the timer in the specified amount of time, or until the retry limit is reached.

The following example shows the missedTaskThreshold attribute configured to enable failover after an interval of ten minutes:
  <persistentExecutor id="defaultEJBPersistentTimerExecutor" missedTaskThreshold="10m"
Enabling and disabling persistent timer task execution

Persistent EJB timer tasks are enabled to run upon commit of the transaction from which they are scheduled. To prevent persistent timer tasks from running on the current server, you can configure the enableTaskExecution attribute with a value of false. In this case, the EJB timer service still writes persistent timer tasks to the database but does not run them on the current server. If failover is enabled and other servers are configured to poll the same database tables, another server eventually finds the timer and runs it. This option can be useful if many servers are configured for timer failover but you want only a subset of them to repeatedly contact the database. If failover is not enabled and the value of the enableTaskExecution attribute is true, the EJB timer service starts running the timers that were previously scheduled and any new timers that are scheduled.

Customizing polling of the persistent store for timer tasks
A single initial poll of the persistent store occurs upon startup to locate any previously scheduled timer tasks. When tasks are scheduled, information about the next scheduled run time is persisted and kept in memory, making further polling of the persistent store unnecessary if failover is disabled. This behavior is ideal in many cases, but might not always be desirable.
  • If the timer tasks have external dependencies on other services, the initial poll might occur too soon and timer tasks might fail if the external services they require are unavailable. In this case, an initial poll delay can be used to defer the initial poll by a fixed amount of time.
  • If many EJB persistent timers are scheduled, they might use too much memory. In this case, you can configure a poll interval to poll the persistent store for only the timer tasks that you want to run within the interval before the next poll. The poll size further limits the number of timer tasks that can be read from the database each poll interval, which might cause some tasks to run late.
In the following example configuration, the initial poll is delayed five minutes and subsequent polls occur every 10 minutes, with a limit of 200 tasks that can be read from the database each poll interval,:
<persistentExecutor id="defaultEJBPersistentTimerExecutor" initialPollDelay="5m" pollInterval="10m" pollSize="200"/>
Retries for failed and rolled back persistent timer tasks

When persistent EJB timer executions fail or are marked to roll back and failover is disabled, they are retried one time immediately. If the immediate retry fails, they are retried at a fixed interval until successful. It is possible to limit the number of retry attempts by specifying a retry limit in the configuration. You can also control the interval between retries (if failover is disabled) by specifying a retry interval in the configuration.

In the following example configuration, retires occur every 2 minutes until the limit of 100 retries is reached:
  <persistentExecutor id="defaultEJBPersistentTimerExecutor" retryLimit="100" retryInterval="2m"/>