|
|
YOUR FEEDBACK
SOA World Conference
Virtualization Conference $200 Savings Expire May 16, 2008... – Register Today! Did you read today's front page stories & breaking news?
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON J2EE
Event-Driven Enterprise JavaBeans
By: Amit Poddar
Digg This!
An event is an asynchronous notification from an external source, such as a thread or another application. Commands from a user, a timer signaling completion of a specified time period, and the arrival of a message in a queue are examples of events. Two components that are generally involved in event-based processing are the event producer and the event consumer. The event producer generates events; the event consumer processes them by taking an action. Event-consumer functionality can be divided into two subcomponents: the listener and the consumer. The listener continuously waits for an event to occur. The moment the event occurs, the listener passes it to the consumer for processing. The event listener's relationship to the consumer can be either one-to-one or one-to-many. The one-to-many relationship is used mostly in scenarios in which the listener listens for multiple types of events and, based on type, dispatches events to the appropriate consumers. Application requirements determine the choice of one model over the other. Whatever the model, the event-based system allows asynchronous processing, in which the event producer doesn't have to wait for the consumer to finish processing. Listeners can collect events in a queue and process them later. The producer component doesn't have to worry about the availability of the consumer. Figure 1 shows a basic event-producer/event-consumer model. There are two message producers; one produces messages of Type A and the other of Type B, and both put messages into the message queue Q1. One listener listens for multiple types of messages, and there are separate consumers for each message type. The listener dispatches messages to the appropriate consumers.
EJB and Event-Driven Processing
In this article, I'll discuss message and timer events in detail, along with how to implement EJBs based on these two event models.
Timer-Driven Bean
You can easily implement this in a non-EJB environment by starting a timer thread that generates timer events at regular intervals. Additional threads act as the event listener and the consumer that processes the orders. The only disadvantage is that the database and the message queue operations can't be put in a single transaction because there is no Distributed Transaction Coordinator (DTC). A great feature of J2EE application servers is the support for distributed transactions. It's advisable to use an EJB hosted under an application server to do the job and maintain transactional integrity. To implement the same functionality in an EJB environment, the most common approach is to write a Java client that acts as the event producer and listener, running outside the application server and invoking an EJB, which consumes the event by taking an action (see Figure 2). Moving the client functionality inside the application server is generally not advised because EJB specifications don't recommend spawning user threads inside an EJB container. This model would work fine, except that if 50 different consumer EJBs are required, this system will need a client application with 50 threads running outside the application server to act as listeners. You might wonder why the listener can't be a single thread that queues all the events and consumes them one by one by invoking the event-consumer EJB serially. Actually, this can be done, but with the loss of the parallel consumption of the events. This wouldn't be acceptable in most real-world applications. The only practical solution is to have 50 listener threads, but this too has limitations. It adds another chance for failure because each call from the client JVM is a remote call to the JVM hosting the consumer EJBs. Also, the system has to run an extra JVM. The easiest way to avoid having a client running outside the application server in a separate JVM is to use an EJB as a user thread. Each EJB runs in a separate thread. EJB specifications prevent creation of user threads inside an EJB container. The trick is using an EJB as a user thread. Whatever functionality is provided by the external client thread can easily be moved inside the application sever using an EJB as a thread. You can easily implement this solution by developing the Timer-Driven Bean (TDB) component. This comprises two EJBs, one acting as the timer event producer and the other acting as the consumer (see Figure 3). In this solution, the external Java client is required only to start and stop the TDB component and doesn't need to be running all the time. All remaining components run inside an application server.
Timer-Producer Bean
Timer-Consumer Bean
Controller Bean
It's important to stop the system gracefully - abruptly shutting down the application server may leave some transactions in an in-doubt state. The correct procedure is to shut down all TDB components gracefully before stopping the application server. Listing 3 shows a single static variable controlling the state of all TDB components. If you have different kinds of consumer beans and want to selectively shut them down based on type, you can maintain bean types and their corresponding state in a hashtable with the controller bean. Since the controller bean isn't involved with any transactional systems, it can be deployed as a stateful session bean with the transaction attribute set to TX_NOT_SUPPORTED.
TDB Launcher and TDB Invoker
TDB Shutdown Agent
Although the sample listings and description of TDB are based on a separate timer-producer and consumer bean, you can merge the functionality of the consumer and the producer into a single EJB.
Message-Driven Bean
A typical example is the system shown in Figure 4, in which a timer-based component (such as TDB) picks up orders from Database 1 and puts them in Q1. A message-handler component picks up order messages from Q1, generates invoices, and puts them in Q2. Another message-handler component reads invoice data from Q2, sends confirmation e-mails to customers, and updates order status in Database 2. You can easily implement a message handler in a non-EJB environment by writing a listener and a consumer. The listener thread waits for messages and on arrival passes them to the consumer for processing. If the processing requires interaction with another transactional resource, such as a database, then the consumer running outside the J2EE environment lacks the transactional integrity provided by a DTC. To achieve transactional integrity, the message consumer should be implemented as an EJB that uses the DTC provided by a J2EE application server. The most common approach to implementing message-driven bean (MDB) functionality in EJB 1.1-based application servers is to provide an external listener to the message queue and an EJB as a message consumer. The listener waits for a message to arrive in the queue. On message arrival, it invokes the message-consumer EJB, passing on the messageID as a parameter (see Figure 5). The listener doesn't process the message itself, but depends upon the consumer EJB to process it. Disadvantages of this type of implementation are:
To solve these problems, an MDB component can be developed in a fashion similar to the TDB implementation, where an external client is required only to start and stop the component (see Figure 6). The main difference between the TDB component and the MDB component is that the latter doesn't need an event producer because the events (messages in the queue) can be generated by other applications. A message-consumer bean (MCB) can also act as a message producer, as shown in Figure 4, where the MDB sitting between Q1 and Q2 acts as message consumer as well as message producer. The components are described below.
Message-Invoker Bean
Message-Consumer Bean
Note: The timer-producer bean sleeps for some time to generate timer events, whereas the message-invoker bean doesn't need to do this. If there are no messages in the queue, the receive(long waitTime) call on the queueReceiver object blocks for the specified time period before returning. This prevents the MDB system from polling the message queues continuously without any delay, which would otherwise result in a high CPU utilization.
Controller Bean
MDB Launcher and MDB Invoker
MDB Shutdown Agent
As with the TDB system, it's possible to merge the functionality of the consumer bean and the invoker bean into a single EJB for the MDB system.
Summary
Additional Features
WEBSPHERE LATEST STORIES . . .
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING WEBSPHERE NEWS
|
||||||||||||||||||||||||||||||