取消@Asynchronous EJB调用

时间:2011-01-24 03:59:33

标签: java asynchronous java-ee ejb ejb-3.1

我正在编写一个企业Java应用程序,它使用异步EJB 3.1方法并行执行许多任务。为了支持取消长时间运行的任务,我一直在尝试使用Future接口。

不幸的是,从客户端应用程序调用{​​{1}}似乎对执行任务的bean的会话上下文没有影响,尽管取消调用正在返回future.cancel(true)

我有一个简单的界面:

true

使用如下bean实现:

public interface AsyncInterface
{
    Future<Integer> run() throws Exception;
}

客户端代码很简单:

@Stateless
@Remote(AsyncInterface.class)
public class AsyncBean
{
    @Resource SessionContext myContext;

    @Asynchronous
    public Future<Integer> run() throws Exception
    {
        Integer result = 0;

        System.out.println("Running AsyncBean");

        while(myContext.wasCancelCalled() == false)
        {
            Thread.sleep(2000);
            System.out.println("Working");
        }      

        System.out.println("AsyncBean cancelled");

        return new AsyncResult<Integer>(result);
     }
}

bean的输出是“工作”的源源不断;它永远不会检测到取消。

如果它是相关的,我正在JBoss Application Server 6.0.0上运行该应用程序。我没有找到使用Future接口的取消功能的示例代码,所以我想知道我是否正确使用Future。这种用法看起来是否正确?是否有更好的选择来取消异步EJB方法调用?

2 个答案:

答案 0 :(得分:3)

回答我自己的问题 - 我发现JBoss AS 6.0.0不支持异步请求的计算。

作为替代方案,我重构了代码以使用JMS请求/响应样式消息传递。

消息驱动bean用于执行异步操作。消息驱动bean创建一个临时队列,并通过JMS将队列返回给调用者。这是通过利用JMS消息的replyTo字段来实现的。

消息驱动bean然后定期检查临时队列中的取消消息。

这比@Asynchronous版本更复杂,但它适用于JBoss AS 6.0.0。

答案 1 :(得分:2)

您必须return Future类型的对象,而不是null。顺便问一下,你没有获得NPE吗?我希望你的代码有问题。

此外,不应调用cancel()See the docs here。顺便说一句,根据docs,不仅不应该调用cancel()方法,也不应该调用实例方法。这就引出了一个问题,那就是为什么一个方法应该返回AsyncResult。我根本不知道,可能是它的未来用途。但是class level comments表明所有方法都是为了方便将结果提供给容器。

因此,我不确定是否可以取消异步EJB调用。

[经过一点研究后编辑]

试试这个实现,

@Stateless
@Remote(AsyncInterface.class)
public class AsyncBean
{
    @Resource SessionContext myContext;

    @Asynchronous
    public Integer run() throws Exception
    {
        Integer result = 0;

        System.out.println("Running AsyncBean");

        while(myContext.wasCancelCalled() == false)
        {
            Thread.sleep(2000);
            System.out.println("Working");
        }      

        System.out.println("AsyncBean cancelled");

        return result;
     }
}