Use the @AccessTimeout notation to prohibit concurrent
client requests or limit how long a method waits for the instance
lock to be granted. By default, the container allows concurrent client
requests, but serializes all method calls and container-invoked callbacks
to prevent multi-threaded access to the stateful session bean instance.
This behavior is like using container-managed concurrency with write
locks for singleton session beans. However, unlike singleton session
beans, stateful session beans cannot be configured to use bean-managed
concurrency and the lock type cannot be changed. Only the access-timeout
value can be modified for stateful session beans.
The following code example illustrates a stateful
session bean with a concurrent access-timeout value that prohibits
concurrent client requests: package com.ibm.example;
@Stateful
public class ShoppingCartBean implements ShoppingCart {
private ArrayList contents = new ArrayList();
@AccessTimeout( value=0 )
public void addToCart (Object o) {
contents.add(o);
}
public Collection getContents() {
return contents;
}
}
package com.ibm.example;
@Stateful
public class ShoppingCartBean implements ShoppingCart {
private ArrayList contents = new ArrayList();
@AccessTimeout( value=0 )
public void addToCart (Object o) {
contents.add(o);
}
public Collection getContents() {
return contents;
}
}
If no annotation is provided,
the default behavior is to wait until a lock is granted. No time limit
exists for how long a client waits for the lock to be granted. Because
nothing is coded at the class level, no wait time limit exists for
a lock to be granted for all methods of the class. If the @AccessTimeout
annotation is used and the container cannot grant the lock within
the specified time limit, a javax.ejb.ConcurrentAccessTimeoutException
exception occurs on the client. The @AccessTimeout annotation only
applies to methods that are declared in the same class as the @AccessTimeout
annotation. For a given class, the metadata for the @AccessTimeout
annotation is never inherited from a class higher in the class inheritance
tree.
An access-timeout value of -1 indicates
that concurrent method calls block access to the bean instance indefinitely
(the default). An access-timeout value of 0 indicates that concurrent
method calls are not allowed. The exception, javax.ejb.ConcurrentAccessException,
occurs when concurrency is detected. And any positive value indicates
the amount of time to wait until the method can proceed.
Prior to Java EE
6, the only concurrency behavior supported for stateful session beans
was an access-timeout of -1, no concurrency. Since the Java EE 6 specification changed the default
behavior, a system property is supported that provides the older default
behavior. See EJB container system properties for more information
about the com.ibm.websphere.ejbcontainer.EE5Compatibility system property.
You can also specify
the @AccessTimeout annotation using the XML deployment descriptor,
and if you use the XML deployment descriptor, the metadata from the
@AccessTimeout annotation is ignored. The following example uses the
XML deployment descriptor to specify the same metadata as the previous
example.
<session>
<ejb-name>ShoppingCartBean</ejb-name>
<concurrent-method>
<method>
<method-name>addToCart</method-name>
</method>
<access-timeout>
<timeout>0</timeout>
<unit>Milliseconds</unit>
</access-timeout>
</concurrent-method>
</session>
It is important to know that the XML coding of the concurrent-methodType
follows the three styles outlined in the EJB specification for composing
the XML for container-transaction method elements. The three styles
are: Style 1 uses the special method
name * to apply the access-timeout value to all business methods for
the specified bean. <!-- Example: Style 1 -->
<concurrent-method>
<method>
<method-name>*</method-name>
</method>
<access-timeout>
<timeout>2000</timeout>
<unit>Milliseconds</unit>
</access-timeout>
</concurrent-method>
Style
2 is used to refer to a business method with a specific name and assign
it the specified access-timeout value. If the method name is overloaded,
meaning multiple methods have the same name but different method signatures,
all methods with this name have the specified access-timeout value.
<!-- Example: Style 2 -->
<concurrent-method>
<method>
<method-name>businessMethod</method-name>
</method>
<access-timeout>
<timeout>2000</timeout>
<unit>Milliseconds</unit>
</access-timeout>
</concurrent-method>
Style 3 is used to refer to a distinct method
that matches the given method name and has a method signature that
matches the method parameters listed. Style 3 takes precedence over
both style 1 and style 2.
<!-- Example: Style 3 -->
<concurrent-method>
<method>
<method-name>businessMethod</method-name>
<method-params>
<method-param>long</method-param>
<method-param>int</method-param>
</method-params>
</method>
<access-timeout>
<timeout>2000</timeout>
<unit>Milliseconds</unit>
</access-timeout>
</concurrent-method>
If style
1 XML is used to define an access-timeout value, then all @AccessTimeout
annotations on the bean are ignored because the method level one is
used instead.