我正在开发一个系统来处理消息并相应地更新数据库,但是我需要在各层之间保持一定程度的隔离。我想到的是以下内容。


MyDao.java:提供数据库访问权限的@Stateless bean。 MyDao使用JPA访问数据库,并由EntityManager注入@PersistenceContext
MyMdb.java:侦听队列的MDB。 MyMdb通过注入MyDao使用@EJB


一次执行MyMdb.onMessage()需要对数据库执行多次访问,包括读取和写入。


一方面,这使我认为@Stateless bean不是MyDao的正确选择:EntityManager中的MyDao实例可以由MyMdb.onMessage()的不同执行随机访问,从而导致线程进行干预彼此。
另一方面,JPA文档说注入的EntityManager只是一个代理:它所操作的实际持久性上下文是绑定到JTA事务的上下文。这样,一切都应该没问题,因为即使EntityManager是“共享的”,每个MDB仍将进行不同的事务,因此可以安全地隔离。


什么是正确的方案?我想念什么吗?

最佳答案

按照您所描述的方式注入到无状态EJB中的实体管理器正是您应该做的。
这种注入提供了一个“容器管理的实体管理器”,它是“事务作用域”的。
因此,在您描述的场景中。


onMessage MDB调用将创建一个事务
对无状态Bean的调用将发生在同一事务上下文中,从而创建一个实体管理器,该管理器将一直存在,直到事务通常在MDB方法返回时才完成。


用于同一EJB实例的特定类型的注入实体管理器无法生存,并且不能在不同的事务之间重复使用。

07-24 09:20