【问题标题】:How can you synchronize two requests from the same user in JSF?如何在 JSF 中同步来自同一用户的两个请求?
【发布时间】:2011-05-04 22:18:05
【问题描述】:

基本上,我的问题是,如果用户单击一个按钮,并等待页面响应,然后单击另一个按钮,似乎存在竞争条件。

如何避免第一个按钮的代码使用与第二个按钮的代码相同的变量?

我怀疑两个请求都会以某种随机顺序调用相同的 getter 和 setter,因为每次按钮单击都将处于 JSF 模型的不同阶段。

这是一个例子。假设用户点击一个按钮,动作函数改变了一些变量。该变量与 getter 和 setter 链接到实际的 jsf 标记。现在假设动作函数完成了 50%。现在用户点击了相同的按钮。 JSf 将调用链接到同一个变量的 getter 和 setter,恢复状态或其他。基本上,该变量被重置为操作更改之前的状态。现在第一次单击的动作函数继续运行,它再次更改变量。即使没有第二个动作调用,它也是一个竞争条件。

【问题讨论】:

    标签: java jsf myfaces


    【解决方案1】:

    在客户端,您可能希望查看 JavaScript 以禁用多个提交,例如单击后禁用提交输入类型。无论如何,这不是一个万无一失的机制。

    在 JSF 本身中,它取决于 Bean 的范围。如果它是会话范围的,您可以同步对其操作方法的访问(即调用应用程序方法),因此一次只有一个线程可以执行逻辑。同样,您可以同步对共享数据的访问。但是,这仅在您具有会话亲和性时才有效。如果你不这样做,你就会挣扎!

    但是,组件树本身(更新值、流程验证等)仍然会为第二个请求调用。也许您可以查看 PhaseListener 或其他东西来防止这种情况发生,但这似乎很棘手,而且可能有点矫枉过正。

    通常,您的应用程序的编码和构建方式意味着您应该能够处理同一用户的多个请求。虽然我个人倾向于使用 JavaScript 方法来防止多个表单提交。你想更详细地解释一下,也许用代码 sn-ps,你发现了什么问题?

    【讨论】:

    • 嗯。我会使用 JavaScript 禁用重复的表单提交。如果您的支持 bean 是请求范围的,那么您将有两个对象,每个对象都独立运行,具有不同的数据。那会是个问题吗?我猜持久性数据应该有一些锁定策略。如果它是会话范围的,您可以查看一些同步,例如在 servlet 过滤器中: synchronized(request.getSession();) { chain.doFilter(req,resp); } ,因此一次只能处理一个绑定到特定会话的请求。
    • 你能提供更多关于servlet过滤的细节吗?
    • 我发现这个thierrywasyl.wordpress.com/2009/06/22/… 很有帮助,这显示了如何获得会话viralpatel.net/blogs/2009/02/…
    猜你喜欢
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多