我知道弄乱 EJB 内的线程是一个很大的禁忌,但我只是想询问如何处理这种情况的建议。我的 EJB 正在调用外部 Web 服务,该服务有时可能返回“忙碌”状态。当发生这种情况时,我想等待一段时间,然后使用与之前相同的数据重新提交请求。
实现这一点的最佳方法是什么?
最佳答案
EJB 3.1 带来了新的 @Asynchronous
feature您可以利用:
@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);
}
然后只需使用以下方式调用您的网络服务:
Future<WebServiceResult> result = yourEJB.callWebService(1);
// Can do some interesting stuff here.
// ...
// ...
result.get(2, SECONDS); // Block for up to 2 seconds.
正如您所看到的,您可以免费获得可配置的重试次数和超时。
这与仅调用 Thread.sleep() 有何不同?返回 Future
更加明确且易于管理。另外,我认为 Thread.sleep() 没有那么有害。唯一的问题是这个 EJB 实例现在不能再被其他客户端重用。在 Future
中,异步调用发生在其他一些 EJB 和线程池中。关于catch block 中Thread#interrupt()
的重要性,请引用Why invoke Thread.currentThread.interrupt() when catch any InterruptException?
另一个想法:在调用 Web 服务时使用方面,捕获一次 BusyException 并重试。
关于jakarta-ee - EJB 中的 Thread.sleep(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8202492/