Factors to Consider When Using This Approach
The framework implementation section showed how the scheduling of tasks is done in a transactional, atomic, all-or-nothing manner. Be aware, however, that each task execution
is performed in a separate transaction. So while you are guaranteed that task scheduling is atomic, the execution is a different matter. This, of course, is the price of executing the tasks in an asynchronous, concurrent manner. Therefore, when scheduling tasks, be sure to set an appropriate timeout to avoid the possibility of the execute method hanging if tasks fail.
As in typical EJB applications, you must exercise proper judgment with regards to exception handling. You must handle the exceptions that the application needs to respond to by placing a try/catch block in the Task's run method. In the try/catch block, you'll decide whether to rollback or commit the transaction depending on your application's requirements. Exceptions that are not handled are propagated to the container, resulting in an automatic transaction rollback.
Since EJB timers are recoverable, tasks must be serialized in case of application server failure. This means that you need to make all relevant task attributes serializable. Conversely, you can make attributes that represent intermediate results transient since they are recalculated when the task is run again.
EJB timers typically invoke the timeout handler in the same VM as the scheduler. Therefore, you should also expect the tasks to be parallelized in the same VM. This is appropriate for the majority of application scenarios. However, in some cases, you may have a very large number of tasks that you prefer to distribute across application cluster members. You can address this in two ways:
- Redefine the scheduling so that a smaller number of tasks are scheduled more often. This results in better distribution across the cluster since scheduling calls are essentially SSB invocations that application servers are capable of distributing.
- Use the queue-based concurrency approach to parallelize tasks across the cluster. This, however, is a more complex and resource-intensive approach to the J2EE concurrency problem.
Most application servers allow you to tune the EJB Timer's thread pool size. You should configure the size to be sufficiently large relative to the number of tasks to be scheduled. Otherwise, multiple tasks may be scheduled on a single thread, resulting in serial behavior.