0

好的,伙计们,让我们去一个奇怪的场景!

我们有 JSF、Spring 和 Hibernate/JPA。

假设我们有一个搜索表单,我们希望根据许多输入进行搜索,并且响应应该返回到表单并显示到网格中。
因此,我们向服务器发送了一些输入并等待响应显示给用户。

问题是什么时候:

当我打开 2 个浏览器并转到同一个表单,并用一些输入填写我的两个表单时,我的网格将显示不正确的结果。

不正确的结果意味着:
表格1:(输入:lineId=10,结果(预期):包含lineId=10的行);
表格2:(输入:lineId=20,结果(预期):包含lineId=20的行);

但是,当我同时单击两个表单上的按钮以调用表单(控制器)的操作时,结果是:

表格1:(输入:lineId=10,结果:包含lineId=20的一行);
表格2:(输入:lineId=20,结果:包含lineId=10的一行);

我的表单范围是:请求
我的服务范围是:单例

我的表单有一个调用按钮操作的方法,该方法将输入发送到我的服务,并在我的服务给出响应后,将其再次发送到表单以进行表示(非常常见的行为)。

我应该说这种情况发生在并发呼叫操作中,当我单击不同步的按钮时,一切正常。!!

怎么了 ?发生了什么?

4

1 回答 1

0

正如我在您的问题中的评论中所述,然后由您发现,问题是由于一个单例 bean 具有一个非单例字段,该字段同时被两个(或更多)线程修改。

如果您正在使用单例 bean,则 bean 不能保持状态,最多可以有静态字段和/或引用另一个 spring 单例 bean 的字段。

任何人都知道为什么当我将范围更改为原型时,这个问题没有像我们预期的那样解决

即使顶部的 spring bean 被作为原型处理,持有该字段的 bean 也是一个单例,所以即使在创建原型 bean 的新实例时,所有这些都包含对同一个单例 bean 的引用。如果你想要一个spring bean来处理状态,它必须是原型。此外,如果您的 bean 是原型,那么所有将使用它的 bean 也必须是原型,否则 Spring只有在创建它的新实例时才会创建一个新的原型 bean(这不会发生在单例 bean 中)。

请注意,这个问题与 JSF无关,与 Spring 配置完全相关。

于 2013-10-13T20:24:14.727 回答