2011-05-04 52 views
0

基本上,我的问题是,如果用户单击一个按钮,并等待页面作出响应,然后单击另一个按钮,似乎有竞争条件。如何在JSF中同步来自同一用户的两个请求?

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

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

这里是一个例子。假设用户点击一个按钮,动作函数改变一些变量。该变量与getter和setter连接到一个真正的jsf标签。现在假设动作函数已完成50%。现在用户点击相同的按钮。 JSf会调用连接到同一变量的getter和setter,恢复状态或其他。基本上,该变量重置为行动改变之前的状态。现在,第一次点击的动作函数将继续运行,并再次更改该变量。即使没有第二次行动电话,这也是一种竞争状态。

回答

1

那么在客户端,你可能想看看JavaScript来禁用多个提交,例如禁用点击后提交输入类型。尽管如此,这不是一个万无一失的机制。

在JSF本身,它取决于Bean的范围。如果它的会话范围可以同步对其操作方法的访问(即调用应用程序方法),因此一次只有一个线程可以执行该逻辑。同样,您可以同步访问共享数据。这只会在你有会话关系时才起作用。如果你不这样做,那么你会奋斗!

但是,组件树本身(更新值,进程验证等)仍将为第二个请求调用。也许你可以看看PhaseListener或者其他的东西来防止这种情况发生,但这看起来很棘手,也许是一种矫枉过正。

通常,应用程序编码和构建的方式意味着您应该能够处理同一用户的多个请求。虽然我个人采用JavaScript方法来防止多个表单提交。你想更详细地解释一下,也许有代码片段,你感觉到了什么问题?

+0

请参阅上面的修改。 – 2011-05-04 22:34:26

+0

嗯。我会禁用使用JavaScript的重复表单提交。如果您的支持bean是请求作用域,那么您将有两个对象,每个对象都独立运行,具有不同的数据。这会是一个问题吗?我想,持久数据应该有一些锁定策略。如果它的会话范围,你可以看看一些同步,例如在servlet过滤器中: synchronized(request.getSession();){ chain.doFilter(req,resp); },所以一次只能为一个特定会话绑定一个请求。 – planetjones 2011-05-04 22:40:19

+0

你可以提供关于servlet过滤的更多细节吗? – 2011-05-05 14:44:08