我正在开发一个系统来处理消息并相应地更新数据库,但我需要在层之间保持一定程度的隔离。我的想法如下。
MyDao.java
:提供数据库访问的@Stateless
bean。MyDao
使用 JPA 访问数据库,并通过@PersistenceContext
注入(inject)EntityManager
。MyMdb.java
:监听队列的 MDB。MyMdb
通过使用@EJB
注入(inject)来使用MyDao
。
MyMdb.onMessage()
的单次执行需要对数据库执行多次访问,包括读取和写入。
- 一方面,这让我认为
@Stateless
bean 并不是MyDao
的正确选择:MyDao
中的EntityManager
实例可能会被MyMdb.onMessage()
的不同执行随机访问,从而导致线程相互干扰。 - 另一方面,JPA 文档表示注入(inject)的
EntityManager
只是一个代理:它操作的实际持久性上下文是绑定(bind)到 JTA 事务的上下文。这样一切都应该没问题,因为即使 EntityManager 是“共享的”,每个 MDB 也会有不同的事务正在进行,从而安全隔离地工作。
什么是正确的场景?我错过了什么吗?
最佳答案
以您所描述的方式注入(inject)无状态 EJB 的实体管理器正是您应该做的。 这种类型的注入(inject)提供了“事务范围”的“容器管理实体管理器”。 所以在你描述的场景中。
- onMessage MDB 调用将创建一个事务
- 对无状态 bean 的调用将发生在相同的事务上下文中,从而创建一个实体管理器,该实体管理器将一直存在,直到事务完成(通常在 MDB 方法返回时)。
同一 EJB 实例的特定类型的注入(inject)实体管理器无法保留,并且不会在不同事务中重复使用。
关于java - 结合 MDB、JPA 和 JTA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51650280/