何时在无状态会话 bean 上使用有状态会话 bean?
Posted
技术标签:
【中文标题】何时在无状态会话 bean 上使用有状态会话 bean?【英文标题】:When to use Stateful session bean over Stateless session bean? 【发布时间】:2013-08-02 18:03:26 【问题描述】:有状态会话 bean 定义如下:
有状态会话 Bean 对象的状态由值组成 它的实例变量。在有状态会话 bean 中,实例 变量表示唯一客户端 bean 会话的状态。因为 客户端与其 bean 交互(“对话”),这种状态通常是 称为会话状态。
无状态会话 bean 定义如下:
无状态会话 Bean 无状态会话 bean 不维护 与客户的对话状态。当客户端调用 无状态 bean 的方法,bean 的实例变量可能包含 特定于该客户端的状态,但仅在 调用。当方法完成时,客户端特定的状态 不应保留。但是,客户可以更改 池化无状态 bean 中的实例变量,并且此状态被保存 转到池化无状态 bean 的下一次调用。除了 在方法调用期间,无状态 bean 的所有实例都是 等效,允许 EJB 容器将实例分配给任何 客户。也就是说,无状态会话 bean 的状态应该适用 跨越所有客户。
使用无状态会话 bean 相对于有状态会话 bean 的优势如下:
因为无状态会话 bean 可以支持多个客户端,所以它们可以 为需要大量数据的应用程序提供更好的可扩展性 的客户。通常,应用程序需要更少的无状态会话 bean 比有状态会话 bean 支持的数量相同 客户。
所以想到的问题是什么时候应该使用有状态会话 bean?根据我对此事的幼稚理解,应该尽可能坚持使用无状态会话 bean。
应该使用有状态会话 bean 的候选对象是什么?有什么好的例子吗?
Session Bean
【问题讨论】:
相关:***.com/questions/8887140/… 【参考方案1】:首先,您必须了解 bean 是如何在服务器上创建和处理的。
对于无状态会话bean,服务器可以在池中维护可变数量的实例。每次客户端请求这样的无状态 bean(例如通过方法)时,都会选择一个随机实例来服务该请求。这意味着如果客户端执行两个后续请求,则无状态 bean 的两个不同实例可能为请求提供服务。实际上,这两个请求之间没有会话状态。此外,如果客户端消失,无状态 bean 不会被销毁,并且可以为来自另一个客户端的下一个请求提供服务。
另一方面,有状态会话 bean 与客户端紧密相连。每个实例都被创建并绑定到单个客户端,并且只为来自该特定客户端的请求提供服务。碰巧的是,如果您在有状态 bean 上执行两个后续请求,您的请求将始终从同一 bean 实例提供。这意味着您可以在请求之间保持对话状态。在生命周期结束时,客户端调用 remove 方法并且 bean 被销毁/准备好进行垃圾回收。
什么时候使用无状态或有状态?
这主要取决于您是否要保持会话状态。例如,如果您有一个将两个数字相加并返回结果的方法,您可以使用无状态 bean,因为它是一次性操作。如果您再次使用其他数字调用此方法,您将不再对先前添加的结果感兴趣。
但是,例如,如果您想计算客户端完成的请求数,则必须使用有状态 bean。在这种情况下,了解客户端之前请求 bean 方法的频率很重要,因此您必须在 bean 中维护会话状态(例如,使用变量)。如果您在此处使用无状态 bean,则每次都会从不同的 bean 为客户端的请求提供服务,这会弄乱您的结果。
【讨论】:
"如果客户端消失,bean 也会被销毁"。实际上,有状态会话 bean 不会自动销毁,除非显式调用由@Remove
(javax.ejb
) 修饰的方法(该方法甚至不需要编码。它可以简单地留空/空白,因为它是由 @ 注释的987654324@)。如果关联的客户端忘记销毁有状态会话 bean,则该 bean 将一直挂在服务器上,直到容器本身决定使用自己的策略将其删除。我错了吗?
你当然是对的。更多关于 bean 生命周期的信息可以在这里找到:docs.oracle.com/javaee/6/tutorial/doc/giplj.html【参考方案2】:
我认为使用 Stateful session bean 的最佳示例是用于 Shopping Cart,您可以在其中存储用户想要购买的所有产品。
【讨论】:
以上是关于何时在无状态会话 bean 上使用有状态会话 bean?的主要内容,如果未能解决你的问题,请参考以下文章
在条件下在无状态会话 Bean 中注入特定的 EntityManager