Here is an example from Part Three: New Features in EJB 3.1 that you can probably adapt:
Asynchronous Invocation of Session Beans
Asynchronous processing is a
surprisingly common requirement for
many enterprise applications. Some of
the most obvious use cases are
triggering fire-and-forget background
processes, handling long-running tasks
while keeping the user interface
receptive or simply increasing
application throughput by utilizing
the benefits of parallel processing.
The easiest way of implementing
asynchronous processing in Java EE
applications today is using Message
Driven Beans. In fact, the first
Message Driven Bean example in EJB 3
in Action is used to implement
asynchronous order billing. More
precisely, a Message Driven Bean
(OrderBillingMDB
) asynchronously
bills the customer after the order is
confirmed and updates the order
information with the results of the
billing attempt once it is completed.
Figure 1 shows this scenario:
Figure 1: Asynchronous order billing
While using Message Driven Beans for
asynchronous processing certainly
works, it also forces you to deal with
messaging and JMS, even for relatively
lightweight functionality. This is
precisely the problem asynchronous
session bean invocation is designed to
solve. With this enhancement, you can
do asynchronous processing simply by
annotating a session bean method with
the @Asynchronous
annotation. Let's
take a look at the re-factored EJB 3
in Action example for asynchronous
billing using the feature:
@Stateless
public class OrderBillingServiceBean implements OrderBillingService {
...
@Asynchronous
public void billOrder(Order order) {
try {
// Attempt to charge the order.
bill(order);
// Send email notification of billing success.
notifyBillingSuccess(order);
order.setStatus(OrderStatus.COMPLETE);
} catch (BillingException be) {
// Send email notification of billing failure.
notifyBillingFailure(be, order);
order.setStatus(OrderStatus.BILLING_FAILED);
} finally {
update(order);
}
}
...
}
Because of the @Asynchronous
annotation, when the client invokes
the OrderBillingService.billOrder
method, the call will return
immediately instead of blocking until
the billOrder
method finishes
executing. The EJB container will make
sure the method gets executed
asynchronously (probably using
messaging under the hood). As you can
see, the return type of the
asynchronous method is void. This will
probably be the case for a vast
majority of asynchronous Session bean
methods. However, EJB 3.1 can also
support a return type of
java.util.concurrent.Future<V>
,
where V
represents the resultant
value of an asynchronous invocation.
In case you are unfamiliar with it,
the Future<V>
interface allows you
to do things like cancelling an
asynchronous invocation, checking if
an invocation is complete, check for
exceptions and getting the results of
an asynchronous invocation. Check out
the documentation for the Future<V>
interface here:
http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html.
Let's take a quick look at an example
using the Future return type. In
the billOrder
method in the previous
example, we set the status of the
order according to the outcome of the
billing attempt and updated the order.
Let's assume that the invoker updates
the order themselves and wants to know
what the status of the billing attempt
was. We could do this by refactoring
the billOrder
method as follows:
@Stateless
public class OrderBillingServiceBean implements OrderBillingService {
...
@Asynchronous
public Future<OrderStatus> billOrder(Order order) {
try {
// Attempt to charge the order.
bill(order);
// Send email notification of billing success.
notifyBillingSuccess(order);
return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE);
} catch (BillingException be) {
// Send email notification of billing failure.
notifyBillingFailure(be, order);
return new AsyncResult<OrderStatus>
(OrderStatus.BILLING_FAILED);
}
}
...
}
The javax.ejb.AsyncResult<V>
object
is a convenience implementation of the
Future<V>
interface. It takes the
result of the asynchronous invocation
as a constructor argument. There's
nothing stopping you from using your
own implementation of Future<V>
however. Asynchronous invocation
supports a few other neat features
like delivery guarantees and
transacted send semantics. For
details, check out the spec draft.
If you have a specific problem, please ask a more specific question :)
See also