0

有一个技术栈:Java EE(WebSpere)、JPA、EJB3、JMS(MDB)、JSF。

架构:JMS 消息到达(通过 MDB)并注册为持久实体 - (使用 EntityManager)。有一个具有无限循环的 Singleton 类负责处理这些实体。Singleton 由 MDB 通知有关创建的实体。最初,实体存储在 Singleton 内的队列中。创建的实体最多可以处理几分钟。不能同时处理超过一定数量的实体(Singleton 中的多个并行进程)。Singleton 不是 EJB,但它使用了 EJB 服务。有一个类表示给定实体的执行上下文(简单 DTO)。

问题是:实体的处理已启动,但 EntityManager 在某个时间点(几秒钟后)开始为搜索请求返回空值,但它不应该,因为就在一秒钟前,实体已更新。

看起来架构不太好。我怀疑 EM 的行为表明,在 MDB 和 Singleton 之间的交互完成后,持久性上下文已经消失了一段时间。单例的生命周期比系统中任何托管 bean 的生命周期长得多。因此,向此类组件注入 EJB 实例(和 EM 实例)似乎根本不是解决方案(将注入的 EJB 实例的引用从 MDB 传递到 Singleton 可能是最糟糕的决定)。

每次需要 EJB 和 EM 时,Singleton 都应该使用 JNDI 查找它们吗?在这种情况下,我是否应该为每个调用锁定 EJB?

您将采用哪种方式设计系统:如果 MDB 仅注册消息(作为实体)。实体的处理可能会稍后开始。而且您必须使用一些 EJB 服务(本地接口)。还有实体管理器。

4

1 回答 1

0

如果 Singleton 使用的实体管理器是事务范围的,那么 Singleton 的生命周期无关紧要。在某种程度上,无状态会话 bean 一旦创建也有无限的生命周期(它们的范围本质上是“无”,但它们的实例被池化并不断被重用)。

每次单例中的方法为请求提供服务时,都会启动一个新事务并附带一个新的持久性上下文,即使实体管理器实例在这些请求中似乎都是相同的。这是正常行为,不应“突然”返回空值。

如果您的单例正在使用适当的锁,则可能值得检查。如果同时访问实体管理器,则这可能是未定义行为的原因。

于 2012-12-13T14:23:53.967 回答