什么时候用有状态session bean,什么时候用无状态session bean
最近,有关于无状态的许多大惊小怪。无状态的缺陷常常被夸大, 它的优点也一样。许多无状态的支持者盲目的宣称无状态能带来 更大的伸缩性;而有状态的支持者争论说必须为了适应无状态 而重建整个系统。真实的情况是什么呢?
通过正确地设计,无状态有以下两个优点: 1.使用stateless bean,EJB容器能容易的pooling和重用bean, 允许少量的bean去服务很多客户端。用stateful bean去做同样 的事情时,bean的状态在方法调用之间必需要钝化和活化,可 能导致I/O瓶颈。所以无状态的一个实际的好处是使用很小的 开销来容易的pool和重用组件。
2.因为一个stateful session bean在内存中缓冲一个客户端 的对话,一个bean失败可能导致失去你的对话。这能导致严重 的反响,如果你不在写bean时考虑到这一点,或者你不使用一 个提供有状态恢复的EJB产品。在一个无状态模型里面,请求 能被透明的重路由到一个不同的组件,因为任何组件都能为 客户端的需要提供服务。
最大的无状态的缺点是你需要在每个方法调用中把客户相关的 的数据推到stateless bean。大多数stateless session bean 将需要接收对一个客户端特定的一些信息,如对banking bean的 银行帐户号码。这些信息要每次一个客户端请求到达时被提供到 stateless bean,因为bean不能对一个特定的客户端保持状态。
一种向bean提供客户相关的数据的方法是把数据作为参数传到 bean的方法中。这可能导致性能下降,然而,只是发生在传递的 数据量很大的情况下。这也阻塞了网络,降低了其他进程的带宽。
另一种为stateless bean提供客户相关的数据的方法,为那个 bean为一个客户端持久性的存储数据。客户端不需要在一个方法 调用中传递所有的状态,而只简单的需要从持久化的storage得到 数据。这里的trade-off又是性能:存储对话持久化的能得到存储 I/O瓶颈,而不是网络I/O瓶颈。
再一种超越无状态的限制的方法是使用JNDI去存储客户相关数据 到一个目录结构。客户端能够等一会传给bean一个在目录结构定位 数据的标识。这和存储数据到数据库很相似。比较大的区别是JNDI 实现能是一个in-memory实现(和共享属性管理器有相同作用,对 com+读者来说应该很熟悉)。如果数据存在内存中,没有数据库会 碰上。
当从有状态和无状态之间选择,你应该问你自己商业进程展开 多调用,需要一个对话?如果是这样,有状态模型应该很合适因 为客户相关的对话能成为bean状态的一部分。相反,如果你的商业 进程变成一个方法调用,无状态能更适合你的需要。
注意如果你要去使用状态,并且你要去建一个基于web的系统, 你可能可以用一个servlet的HttpSession对象去做到这一点,和 stateful session bean大致一样。该用stateful session bean 而不是HttpSession的情况如下: 1.你需要一个事务感知的有状态对象。你的session bean能用 SessionSynchronization来做到这一点。
2.你既有基于web的也有不基于web的客户端来存取你的EJB层, 而且都需要状态。
3.你在使用一个stateful session bean来暂时存储一个商业进程 的暂时状态,这发生在牵扯到多个bean的单个Http请求中。
综上所述,大多数先进的deployment要有复杂而有趣的有状态的 和无状态的组合。使用对你的商业问题最合适的。一个例外是如果 有一个明显的瓶颈,如保持成兆的状态在内存中。而如果你在选择 有状态还是无状态,你会发现有状态可能不是你的首要问题:直到 你测试你的代码,你还在黑暗中乱开枪。如果有状态是你的瓶颈, 如果有必要,你可以重构你的代码。 
|