How it works...

The magic happens in the AsyncTask class, where we will first take a look at the performLookups method:

    private void performLookups() throws NamingException{
Context ctx = new InitialContext();
userTransaction = (UserTransaction)
ctx.lookup("java:comp/UserTransaction");
userBean = (UserBean) ctx.lookup("java:global/
ch09-async-transaction/UserBean");
}

It will give you the instances of both UserTransaction and UserBean from the application server. Then you can relax and rely on the things already instantiated for you.

As our task implements a Callabe<V> object that it needs to implement the call() method:

    @Override
public User call() throws Exception {
performLookups();
try {
userTransaction.begin();
User user = userBean.getUser();
userTransaction.commit();
return user;
} catch (IllegalStateException | SecurityException |
HeuristicMixedException | HeuristicRollbackException
| NotSupportedException | RollbackException |
SystemException e) {
userTransaction.rollback();
return null;
}
}

You can see Callable as a Runnable interface that returns a result. 

Our transaction code lives here:

            userTransaction.begin();
User user = userBean.getUser();
userTransaction.commit();

And if anything goes wrong, we have the following:

        } catch (IllegalStateException | SecurityException | 
HeuristicMixedException | HeuristicRollbackException
| NotSupportedException | RollbackException |
SystemException e) {
userTransaction.rollback();
return null;
}

Now we will look at AsyncService. First, we have some declarations:

    private AsyncTask asyncTask;

@Resource(name = "LocalManagedExecutorService")
private ManagedExecutorService executor;

@PostConstruct
public void init(){
asyncTask = new AsyncTask();
}
We are asking the container to give us an instance from ManagedExecutorService, which It is responsible for executing the task in the enterprise context.

Then we call an init() method, and the bean is constructed (@PostConstruct). This instantiates the task.

Now we have our task execution:

    @GET
public void asyncService(@Suspended AsyncResponse response){

Future<User> result = executor.submit(asyncTask);

while(!result.isDone()){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}

try {
response.resume(Response.ok(result.get()).build());
} catch (InterruptedException | ExecutionException ex) {
System.err.println(ex.getMessage());
response.resume(Response.status(Response.
Status.INTERNAL_SERVER_ERROR)
.entity(ex.getMessage()).build());
}

}

Note that the executor returns Future<User>:

Future<User> result = executor.submit(asyncTask);

This means this task will be executed asynchronously. Then we check its execution status until it's done:

        while(!result.isDone()){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ex) {
System.err.println(ex.getMessage());
}
}

And once it's done, we write it down to the asynchronous response:

response.resume(Response.ok(result.get()).build());
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.210.205