Use this task to configure Enterprise JavaBeans (EJB) 3.1
session bean methods to run asynchronously. You can make some or all
of your bean methods asynchronous.
Before you begin
Attention: In EJB 3.1 modules, you can set one
or more session bean methods to be asynchronous, broadening parallel
processing in your application.
- If you are not already familiar with EJB 3.1 asynchronous methods,
read about EJB 3.1 asynchronous methods, client programming model
for EJB asynchronous methods, bean implementation programming model
for EJB asynchronous methods, and EJB container work manager for asynchronous
methods. The topics provide an overview of EJB 3.1 asynchronous methods,
describe the client and bean implementation programming models, and
discuss the work manager that the EJB container uses to dispatch asynchronous
methods.
- Develop a new EJB 3.1 session bean for your application, or change
an existing session bean so that it conforms to the EJB 3.1 programming
model requirements for asynchronous methods. For general information,
see information about developing enterprise beans.
About this task
After you have developed a session bean, complete the following
steps to make one or more of the bean methods asynchronous.
Procedure
- Specify one or more methods of the bean implementation
class as asynchronous. This can be accomplished by adding @Asynchronous
annotations in your bean source code, by adding <async-method>
stanzas in your module deployment descriptor, or by adding a combination
of both annotations and deployment descriptor stanzas.
You can apply the @Asynchronous annotation or its superclasses only,
to your bean implementation class. It cannot be applied to interface
classes. Also, when the annotation is applied at the class level,
all methods of that class are asynchronous. Likewise, all methods
of a bean can be configured as asynchronous by applying "*" as the
<method-name> in your deployment descriptor.
See the following examples of applying the @Asynchronous annotation:
- Apply the @Asynchronous annotation to one method of a bean with
a no-interface view. In this example, the m1 method is synchronous
and the m2 method is asynchronous.
@Stateless @LocalBean
public class MyLocalBean {
public void m1() {
// method code
}
@Asynchronous
public Future<String> m2() {
// method code
return new javax.ejb.AsyncResult("Hello, Async World!");
}
}
Important: The javax.ejb.AsyncResult<V> object is a convenience implementation
of the Future<V> interface. See the API documentation for more
details.
- Apply the @Asynchronous annotation
to the class level of a bean class. In this example, both the m1 method
and the m2 method are asynchronous on this no-interface view bean.
@Stateless @LocalBean @Asynchronous
public class MyLocalBean {
public void m1() {
// method code
}
public Future<String> m2() {
// method code
return new javax.ejb.AsyncResult("Hello, Async World!");
}
}
- Apply the @Asynchronous annotation to one method of a bean implementation
class. In this example, the m1 method is synchronous and the m2 method
is asynchronous. This example also demonstrates how the return types
might differ between the business interface and the implementation
class.
public interface MyIntf {
public void m1();
public Future<Integer> m2();
}
@Stateless @Local(MyIntf.class)
public class MyBean {
public void m1() {
// method code
}
@Asynchronous
public Integer m2() {
// method code
return new Integer(3);
}
}
- Apply the @Asynchronous annotation
to the class level of a bean implementation class. In this example,
both the m1 method and the m2 method are asynchronous.
@Stateless @Local(MyIntf.class) @Asynchronous
public class MyBean {
public void m1() {
// method code
}
public Integer m2() {
// method code
return new Integer(8);
}
}
See the following examples of modifying
the EJB module deployment descriptor,
ejb-jar.xml:
- In this example all business methods of the FullAyncBean bean
implementation class and its superclasses are configured as asynchronous
with the wildcard (*) method-name element.
<session>
<display-name>FullAsyncEJB</display-name>
<ejb-name>FullAsyncBean</ejb-name>
<business-local>com.ibm.sample.async.ejb.FullAsyncIntf</business-local>
<ejb-class>com.ibm.sample.async.ejb.FullAsyncBean</ejb-class>
<session-type>Stateless</session-type>
<async-method>
<method-name>*</method-name>
</async-method>
</session>
- In this example only the specified methods and signatures -- all
methods named m1 and the method m2 with a single String parameter
-- are configured as asynchronous on the PartiallyAsyncBean bean implementation
class.
<session>
<display-name>PartiallyAsyncEJB</display-name>
<ejb-name>PartiallyAsyncEJB</ejb-name>
<business-local>com.ibm.sample.async.ejb.PartiallyAsyncIntf</business-local>
<ejb-class>com.ibm.sample.async.ejb.PartiallyAsyncBean</ejb-class>
<session-type>Stateless</session-type>
<async-method>
<method-name>m1</method-name>
</async-method>
<async-method>
<method-name>m2</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</async-method>
</session>
See the following
examples of applying a combination of the @Asynchronous annotation
in the bean source code and modifying the EJB module deployment descriptor,
ejb-jar.xml:
- In this example the @Asynchronous annotation configures method
m2 to be asynchronous, and the deployment descriptor configures method
m1 to also be an asynchronous method.
@Stateless @LocalBean
public class MyLocalBean {
public void m1() {
// method code
}
@Asynchronous
public Future<String> m2() {
// method code
return new javax.ejb.AsyncResult("Hello, Async World!");
}
}
<session>
<display-name>MyLocalEJB</display-name>
<ejb-name>MyLocalEJB</ejb-name>
<local-bean/>
<ejb-class>com.ibm.sample.async.ejb.MyLocalBean</ejb-class>
<session-type>Stateless</session-type>
<async-method>
<method-name>m1</method-name>
</async-method>
</session>
- In this example the @Asynchronous
annotation for method m2 is ignored because the deployment descriptor
header contains the metadata-complete="true" flag. This flag causes
configuration information to only be taken from the deployment descriptor
elements. The result is that only method m1 of the MyLocalBean implementation
is configured to be asynchronous.
@Stateless @LocalBean
public class MyLocalBean {
public void m1() {
// method code
}
@Asynchronous
public Future<String> m2() {
// method code
return new javax.ejb.AsyncResult("Hello, Async World!");
}
}
<ejb-jar id="ejb-jar_ID" ...
metadata-complete="true" version="3.1">
...
<session>
<display-name>MyLocalEJB</display-name>
<ejb-name>MyLocalEJB</ejb-name>
<local-bean/>
<ejb-class>com.ibm.sample.async.ejb.MyLocalBean</ejb-class>
<session-type>Stateless</session-type>
<async-method>
<method-name>m1</method-name>
</async-method>
</session>
...
</ejb-jar>
- Verify that the transaction attribute applied to any asynchronous
method is either REQUIRED, REQUIRES_NEW, or NOT_SUPPORTED.
These transaction attribute types are the only transaction attribute
types supported on asynchronous methods. You can complete this action
by either applying @TransactionAttribute annotations in the bean source
code, by adding <container-transaction> stanzas in the
ejb-jar.xml file, or by adding a combination of both annotations
and <container-transaction> stanzas in the deployment descriptor.
See the following example of setting the transaction
attribute of an asynchronous method using annotations:
@Singleton @LocalBean
public class FullAsyncBean {
@Asynchronous
@TransactionAttribute(REQUIRED) // the default; specified for illustration
public void m1() {
// ...
}
@Asynchronous
@TransactionAttribute(NOT_SUPPORTED)
public void m2() {
// ...
}
@Asynchronous
@TransactionAttribute(REQUIRES_NEW)
public void m3() {
// ...
}
// ...
}
See the
following example of setting the transaction attribute of an asynchronous
method using the XML deployment descriptor:
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>FullAsyncBean</ejb-name>
<method-name>m1</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>FullAsyncBean</ejb-name>
<method-name>m2</method-name>
</method>
<trans-attribute>NotSupported</trans-attribute>
</container-transaction>
<container-transaction>
<method>
<ejb-name>FullAsyncBean</ejb-name>
<method-name>m3</method-name>
</method>
<trans-attribute>RequiresNew</trans-attribute>
</container-transaction>
</assembly-descriptor>
See the
following example of using a combination of both annotations and the
XML deployment descriptor to configure the transaction attributes
of a bean. In this example the deployment descriptor stanzas for method
m3 override the class level annotation. The result is that method
m3 is configured as REQUIRES_NEW, while methods m1 and m2 are configured
as REQUIRED:
@Singleton @LocalBean
@Asynchronous
@TransactionAttribute(REQUIRED) // the default; specified for illustration
public class FullAsyncBean {
public void m1() {
// ...
}
public void m2() {
// ...
}
public void m3() {
// ...
}
// ...
}
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>FullAsyncBean</ejb-name>
<method-name>m3</method-name>
</method>
<trans-attribute>RequiresNew</trans-attribute>
</container-transaction>
</assembly-descriptor>
What to do next
Continue to develop additional components for
your application, or if you have finished all components required
by your application, assemble and deploy your application. See information
about assembling EJB modules and deploying EJB modules.
When you run your application, if it fails when it first attempts
to use a session bean that has an asynchronous method, a configuration
error might exist. Check the system log file for configuration error
messages.
Analyze the trace data or forward it
to the appropriate organization for analysis. EJB asynchronous method
scheduling and invocation are traced in the EJB container trace. For
instructions on enabling this trace see the information about enabling
trace on a running server. To analyze trace data, see information
about trace output.