什么时候用有状态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要有复杂而有趣的有状态的
和无状态的组合。使用对你的商业问题最合适的。一个例外是如果
有一个明显的瓶颈,如保持成兆的状态在内存中。而如果你在选择
有状态还是无状态,你会发现有状态可能不是你的首要问题:直到
你测试你的代码,你还在黑暗中乱开枪。如果有状态是你的瓶颈,
如果有必要,你可以重构你的代码。