2011-06-13 49 views
3

基于这篇文章http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the我使用我的应用程序@Named @Stateless bean与数据库进行通信(在此注入EntityManager)并在jsf页面上显示信息。从Java EE 5开始,这非常便利,但我有一个问题。我可以使用具有CDI的EJB Stateless Bean来维护用户会话吗?

使用这些bean来维护用户会话(购物车等)是否安全?我读了一本关于ejb 3.0的书,我知道相同的无状态bean可以与许多客户端一起使用。

与所有ejb功能(交易,线程安全等)一起使用托管bean的最佳方法是什么?我的意思是与Java EE 5中的实现+ ejb注入相比,托管bean + ejb接口还有其他方法吗?

我使用GlassFish 3.1 WebProfile

+0

感谢您的回答,那么我应该使用@Named @Stateful还是jsf会话?哪个更好/轻量级?当用户关闭浏览器和ejb会话时,jsf会话结束? – m1m 2011-06-13 10:08:42

+0

或者可能将ENtityManager注入ManagedBean?它安全吗? – m1m 2011-06-13 10:15:23

+1

当用户关闭浏览器时,EJB会话不一定会结束,但Web用户将无法在稍后再次与EJB会话连接。 EJB代理通常保存在http会话,对话或视图范围内,当主要http会话结束时,这些都会被销毁。 – 2011-06-13 12:26:31

回答

6

无状态bean无法维护购物车或会话;这就是“无国籍”的意思。

您需要有状态的EJB或在Web层中执行此操作。这些是会话维护的唯一地点。

10

添加到duffymo的建议;使用有状态会话bean与使用HTTP会话相比,还有一些其他注意事项。

HTTP会话基本上有一个像结构的地图。它直接适用于会话中的所有线程(请求)。这使得操纵几个项目成为相对不安全的行为。可以在会话本身上进行同步,但这是一项风险很大的操作,可能会使整个应用程序失效。 HTTP会话确实允许你声明事件监听器,它会触发http会话的任何修改。

有状态会话bean当然有一个bean结构。它具有一种自动同步功能,因为只有线程可以在bean中同时处于活动状态。通过注释,你可以声明其他线程是否等待(如果是这样,等待多久),或者在并发访问面前立即抛出异常。

通常每个用户只有一个http会话,一个用户可以同时使用多个有状态会话bean。有状态会话bean的一个特别的优点是它们有一种机制可以在某个超时后钝化它们的状态,这可以释放你服务器的内存(当然是以磁盘空间为代价的)。有状态会话bean不直接拥有http会话所具有的事件侦听器类型。

我认为最初有状态会话bean的“会话”方面是维持与远程非Web客户端(Swing,另一个AS等)的会话。这很像创建http会话以维持与远程Web客户端的会话。由于非Web客户端可以请求并保留有状态会话Bean的多个代理,因此Web类比实际上更类似于最近引入的conversation scope

在远程web客户端与服务器通话的情况下,服务器与有状态会话bean进行内部对话,概念有很大的重叠。远程Web客户端只知道http会话(通过JSESSIONID),而不了解有状态会话Bean的会话。因此,如果http会话丢失,您通常无法再将远程客户端与特定的有状态会话bean连接起来。在这种情况下,HTTP会话总是处于领先地位,您可能还会将您的购物车项目存储在单个(http)会话作用域bean中。

有一种特定情况,其中有状态会话bean派上用场进行内部通信,这就是如果您需要JPA的extended persistence context。这可以在例如使用时使用。对实体的锁定需要在请求之间持续(如果您的股票数量有限,可能对于购物车来说很方便,并且一旦他实际签出就不想与用户发生“缺货”消息)。

相关问题