Use a work manager as a ContextService to contextualize invocation of an interface and
specify execution properties to control how thread context is captured and applied to the thread of
execution.
About this task
Application components that require thread context to be present when methods of an object are
invoked can use a work manager, which implements
javax.enterprise.concurrent.ContextService, to construct a contextual proxy for the
object. Thread context is captured, per the settings of the work manager, when the contextual proxy
is created. When interfaces methods are invoked on the contextual proxy, the previously captured
thread context is applied prior to invocation and restored afterward.
You can specify execution properties for a contextual proxy to control how thread context is
captured and applied. For example, contextual proxy methods are invoked with any transaction already
on the thread of execution thread suspended, unless an execution property is used to override this
behavior.
- Define an interface (or choose an existing interface that is suitable) with the methods that
require thread context.
public interface AddressFinder {
Address getAddress(Person p) throws Exception;
}
- Provide an implementation of the interface:
public class DatabaseAddressFinder implements AddressFinder {
private final String resRefLookupName;
public DatabaseAddressFinder(String resRefLookupName) {
this.resRefLookupName = resRefLookupName;
}
public Address getAddress(Person p) throws Exception {
// Resource reference lookup requires the thread context of the
// application component that defines the resource reference.
DataSource ds = (DataSource) new InitialContext().lookup(
resRefLookupName);
Connection con = ds.getConnection();
try {
ResultSet r = con.createStatement().executeQuery(
"SELECT STREETADDR, CITY, STATE, ZIP " +
"FROM ADDRESSES WHERE PERSONID=" + p.id);
if (r.next())
return new Address(r.getString(1), r.getString(2),
r.getString(3), r.getInt(4));
else
return null;
} finally {
con.close();
}
}
}
- Use a context service to capture context from the current thread and wrap an instance with that
context, while applying a set of execution properties:
ContextService contextService = (ContextService) new InitialContext().lookup(
"java:comp/DefaultContextService");
Map<String, String> executionProperties =Collections.singletonMap(
ManagedTask.TRANSACTION,
ManagedTask.USE_TRANSACTION_OF_EXECUTION_THREAD)
AddressFinder addressFinder = contextService.createContextualProxy(
new DatabaseAddressFinder("java:comp/env/jdbc/MyDataSourceRef"),
executionProperties,
AddressFinder.class);
- From another thread, use the contextual proxy to invoke methods under the context of the
original thread.
transaction.begin();
try {
Address myAddress = addressFinder.getAddress(me);
updateShippingInfo(myAddress);
} finally {
transaction.commit();
}