我知道搞乱EJB中的线程是一个很大的禁忌,但我想就如何处理这种情况征求意见.我的EJB正在调用外部Web服务,有时可能会返回"忙"状态.当发生这种情况时,我想等待一段时间,然后使用与以前相同的数据重新提交请求.
实现这个的最佳方法是什么?
Tom*_*icz 13
EJB 3.1带来了一个可以利用的新@Asynchronous 功能:
@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);
}
Run Code Online (Sandbox Code Playgroud)
然后简单地通过以下方式呼叫您
Future<WebServiceResult> result = yourEJB.callWebService(1);
// Can do some interesting stuff here.
// ...
// ...
result.get(2, SECONDS); // Block for up to 2 seconds.
Run Code Online (Sandbox Code Playgroud)
如您所见,您可以免费获得可配置的重试次数和超时.
这与仅仅打电话有Thread.sleep()什么不同?返回Future更明确,更易于管理.我也不认为那Thread.sleep()是有害的.唯一的问题是这个EJB实例现在可以更长时间被其他客户端重用.随着Future异步调用里面发生一些其他的EJB和线程池.至于Thread#interrupt()catch块内部的重要性,请参考为什么在捕获任何InterruptException时调用Thread.currentThread.interrupt()?
另一个想法:使用方面调用Web服务,捕获BusyException一次并重试.
Ósc*_*pez 11
在EJB限制常见问题解答中,它明确指出了您
不应该创建或管理线程
将一个线程置于睡眠状态算作"管理"它.
在您的情况下,当Web服务返回"忙"状态时,您可以安排作业在稍后的时间点重试发送消息,例如使用Quartz Scheduler.执行将在那里结束,并且应该将任何进一步的处理委托给作业调度程序.
| 归档时间: |
|
| 查看次数: |
10042 次 |
| 最近记录: |