Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I know that messing with threads inside an EJB is a big no-no, but I would just like to ask for advice on how handle this case. My EJB is calling an external Web service which may sometimes return a "busy" status. When that happens, I would like to wait for a while and then resubmit the request using the same data as before.

What would be the best way to implement this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
542 views
Welcome To Ask or Share your Answers For Others

1 Answer

EJB 3.1 brought a new @Asynchronous feature that you can take advantage of:

@Asynchronous
@TransactionAttribute(NOT_SUPPORTED)
public Future<WebServiceResult> callWebService(int retries) {
    WebServiceResult result = webService.call();

    if (!result.equals(BUSY)) {
        return result;
    }

    if (retries <= 0) {
        throw new TooBusyException();
    }

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

    return callWebService(retries - 1);
}

Then simply call you web service with:

Future<WebServiceResult> result = yourEJB.callWebService(1);

// Can do some interesting stuff here.
// ...
// ...

result.get(2, SECONDS);  // Block for up to 2 seconds.

As you can see you get configurable number of retries and timeout for free.

How does this differ from just calling Thread.sleep()? Returning Future is more explicit and manageable. Also I don't think Thread.sleep() is that harmful. The only problem is that this EJB instance can now longer be reused by other clients. With Future asynchronous invocation happens inside some other EJB and thread pool. As to importance of Thread#interrupt() inside the catch block, refer Why invoke Thread.currentThread.interrupt() when catch any InterruptException?

Another idea: use aspect around calling web service, catch BusyException once and retry.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...