我可以使用带有CDI的EJB无状态Bean来维护用户会话吗?

时间:2011-06-13 09:41:36

标签: java jsf-2 java-ee-6 cdi ejb-3.1

基于这篇文章http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the我在我的app @Named @Stateless bean中使用与数据库进行通信(在此处注入EntityManager)并在jsf页面上显示信息。自Java EE 5以来,这是很好的促进,但我有一个问题。

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

使用具有所有ejb功能(事务,线程安全等)的托管bean的最佳方法是什么?我的意思是除了Java EE 5中的带有实现+ ejb注入的托管bean + ejb接口以外的任何其他方式吗?

我使用GlassFish 3.1 WebProfile

2 个答案:

答案 0 :(得分: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。这可以用于例如实体上的锁定需要在请求之间持续(如果您的库存有限,并且在实际结账时不想用“缺货”消息与用户对话,这对于购物车来说可能很方便)。 p>

答案 1 :(得分:6)

无国籍豆无法维护购物车或会话;这就是“无国籍”的含义。

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