0

我有一个 2 应用程序。一个是应用程序客户端,另一个是 EJB 项目。我的客户端引用了服务器端。容器托管 Bean 事务用于 bean。我不能使用以下语句将实体管理器注入 bean。

@PersistenceContext(unitName = "DBService")
private EntityManager em;

我在服务器端有一个消息驱动 bean、2 个无状态 bean 和一个单例 bean 。我从消息驱动bean本地注入2个无状态bean。根据JMS消息的消息类型(它来自服务器或客户端),消息驱动bean调用相关有状态bean的业务方法。每个无状态bean都注入单例bean .

我正在对单例 bean 中的实体进行一些更改,更新实体的某些字段,我正在向客户端或服务器发送 jms 消息。当消息由 2 个无状态 bean 处理时,它调用单例 bean 的业务方法。例如我改变了一个实体的字段。然后单例bean向客户端发送jms消息,然后客户端做一些工作,然后他将消息发送回服务器,服务器在消息驱动bean中消费这个消息,然后它调用相关的无状态bean的业务方法,然后无状态均值调用单例bean的业务方法。然后我正在从数据库中查询,但是我看不到更改实体的最新状态。我的更改被覆盖了。我认为如果 Singleton bean 的 EntityManager 由多个 bean 注入,它就不能正确地保持实体的状态。我认为必须从连接池中获取相同的单例 bean 实例。我对此有严重的问题。

你认为我的检测是正确的吗?还是我做错了什么?

问题:我认为当一个无状态bean调用singleton bean的方法新事务开始时,然后第二个无状态bean调用singleton bean的方法,它也启动了一个事务,但是前一个没有提交,2个事务不知道变化这是彼此的。但我不知道如何解决这个问题。使用 Bean 托管事务是单例 bean 的一个很好的解决方案吗?

4

1 回答 1

0

默认情况下,带有注释的 bean@Singleton是容器管理的,并且使用锁定模式LockType.WRITE,可以显式应用@ConcurrencyManagement(CONTAINER)

如果客户端正在调用任何方法,则所有其他请求都必须等待前一个调用返回。在这里,您可以将锁应用于单例 bean 的入口方法,然后可以从内部调用其他方法。

您还可以在方法级别使用 进行注释@Lock(LockType.WRITE)。因此,调用的顺序将与客户端调用它们的顺序有关。


编辑:对单例 bean 的并发访问是序列化的,默认情况下方法具有REQUIRED事务属性。

因此容器在客户端的事务上下文中调用 bean 的方法。因此,他们将拥有从无状态 bean 到单例 bean 的单独事务。

Stateless Bean A ----->                          ---> Read/Write 
Stateless Bean B ----->  |C|B| Singleton --> |A| ---> Read/Write
Stateless Bean C ----->                          ---> Read/Write

如上所述,来自 bean B & C 的请求将被序列化/排队,直到 A 尚未完成。所以所有的请求都会被单独处理而不影响其他请求,但可能会导致性能瓶颈。

您可以应用方法级别锁定,@Lock(LockType.WRITE)用于更改共享数据@Lock(LockType.READ)的方法和访问它们的方法。

于 2012-10-15T08:44:17.990 回答