CDI会话Bean - BusyConversationException

时间:2015-08-11 10:40:08

标签: cdi weld conversation-scope

我有一个Conversation scoped bean,ComponenteM,它被注入一个Request Scoped bean,ComponenteC。

@Named
@RequestScoped
public class ComponenteC implements Serializable {
    @Inject
    ComponenteM componenteM;
}


ComponenteC有一个由HtmlCommandLink(以编程方式创建)调用的导出方法。导出方法调用与SAP BO Web服务集成的Web服务,以便将报告导出到Excel。但是,仅在调用时间过长时,我得到一个BusyConversationException。每个其他出口需要不到10分钟的成功。 我同时在谈话中没有其他电话(AJAX或非AJAX电话)。 我开始尝试在开始对话时为对话bean设置显式的timout,但我读到它只是作为对CDI容器的建议,可能会被忽略:

public void beginConversation() {
    if (conversation.isTransient()) {
        conversation.setTimeout(60 * 60 * 1000);
        conversation.begin();
    }
}


错误是:
ServletException.org.jboss.weld.context.BusyConversationException的根本原因:WELD-000322对话锁定超时:1

我还尝试通过线程发出导出请求,然后将导出的文档返回到会话中。我的想法是让一个线程忙着处理文件和componenteC的导出,在等待线程完成的时候,会偶尔检查一下componenteM.beginConversation();


我试图理解为什么即使没有并发请求也会抛出BusyConversationException。
谢谢。

1 个答案:

答案 0 :(得分:0)

我最近在应用程序中遇到了同样的问题。元素的异步加载工作正常,除了带有@ConversationScoped的一页。

我的解决方案是简单地使这一页的请求同步。 在此页面上,使用PrimeFaces的“ deferred”参数异步加载元素,如下所示:

<p:outputPanel id="asyncMenu" deferred="true">...</p:outputPanel>

当我将参数设置为“ false”时,一切按预期进行。 @ConversationScoped引入了URL参数“ cid”,因此仅在具有cid的网站上才将deferred设置为“ false”:

<p:outputPanel id="asyncMenu" deferred="#{empty param.cid ? true : false}">...</p:outputPanel>

虽然感觉有些古怪,但在我看来,它可以很好地工作,而且如果我们决定依靠@ConversationScoped添加新页面,将来也可以使用。