如何为EJB中的下一次调用保留无状态bean的实例变量的状态?

时间:2014-10-10 22:39:02

标签: java-ee ejb state

我正在阅读Java EE7 documentation,这就是无状态bean所说的内容。我对下面用粗体标记的声明的含义感到困惑

无状态会话bean不与客户端保持会话状态。当客户端调用无状态bean的方法时,bean的实例变量可能包含特定于该客户端的状态,但仅限于调用期间。方法完成后,不应保留特定于客户端的状态。但是,客户端可能会更改池化无状态bean中实例变量的状态,并且此状态将保留到池化无状态bean的下一次调用。除了在方法调用期间,无状态bean的所有实例都是如此。是等价的,允许EJB容器将实例分配给任何客户端。也就是说,无状态会话bean的状态应该适用于所有客户端。

然而,从这篇文章来看, instance variables in stateless session beans

无状态会话bean是一个没有关联会话状态但可能具有实例状态的对象。它不允许并发访问bean。实例变量的内容不保证跨方法调用保留。客户端应认为无状态会话bean的所有实例都是相同的。

我觉得这里有矛盾。文档声称(根据我的理解)实例变量状态在下一次调用中保留,而后者声明无法保证状态得到保留。

请解释

P.S:我确实看过这篇文章:但我没有理解答案

instance variables in stateless session beans

编辑形成上面的SO帖子

无状态会话Bean(SLSB)不依赖于一个客户端,并且无法保证一个客户端在每次方法调用时获取相同的实例(某些容器可能会在每个方法调用会话中创建和销毁bean,这是一个实现特定的决定,但实例通常是合并的 - 我没有提到集群环境)。换句话说,尽管无状态bean可能具有实例变量,但这些字段并非特定于一个客户端,因此不要在远程调用之间依赖它们。

1 个答案:

答案 0 :(得分:9)

  1. SLSB通常以倍数创建,并存储在池中。因此,对于EJB UserDataService,将创建和汇集许多实例

  2. 当客户端请求UserDataService的服务时,容器将为其中一个池实例提供服务。 任何一个。当两个客户端请求同一EJB的服务时,将有两个单独的实例服务

  3. 当客户端使用SLSB时,正在使用的实例通常会返回到池中,不会被销毁 。这意味着在容器启动时创建的相同的唯一EJB对象可能会在容器的正常运行时间内充分存在于堆上。需要重复的是:容器首次将EJB投入使用时创建和汇集的相同SLSB通过容器的正常运行时间保持活动

  4. (3)的意思是,如果(2)中的客户端在从池中获取的EJB实例上设置了任何变量,并且将EJB放回池中,那么下一个获取的客户端该实例将能够看到对该EJB状态所做的更改(回想一下,池中有一些(有点)固定数量的EJB实例,并且它们在请求服务的各个客户端之间循环)。 p>

  5. 无法保证请求客户端的UserDataService具体实例。无法保证(2)中的客户端将在针对该EJB的两个单独请求上获得UserDataService的相同实例。这就是无会话状态的含义。 您无法保证在多次调用中与该EJB的同一实例进行通信。这并不意味着EJB在请求中被销毁,只是在循环过程中,您无法确定客户端将与哪个实例相关联