结合 MDB、JPA 和 JTA
Combining MDB, JPA and JTA
我正在开发一个系统来处理消息并相应地更新数据库,但我需要在层之间保持一定程度的隔离。我想到了以下内容。
MyDao.java
:提供数据库访问的 @Stateless
bean。 MyDao
使用 JPA 访问数据库,EntityManager
由 @PersistenceContext
注入。
MyMdb.java
:监听队列的MDB。 MyMdb
通过注入 @EJB
. 使用 MyDao
MyMdb.onMessage()
的一次执行需要对数据库执行多次访问,包括读取和写入。
- 一方面,这让我认为
@Stateless
bean 不是 MyDao
的正确选择:MyDao
中的 EntityManager
实例可能是随机的由 MyMdb.onMessage()
的不同执行访问,导致线程相互干扰。
- 另一方面,JPA 文档说注入的
EntityManager
只是一个代理:它运行的实际 持久性上下文 是绑定到JTA 事务。这样一切都应该没问题,因为即使 EntityManagers 是 "shared",每个 MDB 都会有不同的事务正在进行,因此可以安全隔离地工作。
什么是正确的场景?我错过了什么吗?
以您描述的方式注入无状态 EJB 的实体管理器正是您应该做的。
这种类型的注入提供了 'Container-Managed Entity Manager' 即 'transaction scoped'。
所以在你描述的场景中。
- onMessage MDB 调用将创建一个事务
- 对无状态 bean 的调用将发生在相同的事务上下文中,创建一个实体管理器,该管理器通常在 MDB 方法 returns.
时一直存在到事务完成为止
同一 EJB 实例的特定类型的注入实体管理器不会存在,并且不会在不同的事务中重复使用。
我正在开发一个系统来处理消息并相应地更新数据库,但我需要在层之间保持一定程度的隔离。我想到了以下内容。
MyDao.java
:提供数据库访问的@Stateless
bean。MyDao
使用 JPA 访问数据库,EntityManager
由@PersistenceContext
注入。MyMdb.java
:监听队列的MDB。MyMdb
通过注入@EJB
. 使用
MyDao
MyMdb.onMessage()
的一次执行需要对数据库执行多次访问,包括读取和写入。
- 一方面,这让我认为
@Stateless
bean 不是MyDao
的正确选择:MyDao
中的EntityManager
实例可能是随机的由MyMdb.onMessage()
的不同执行访问,导致线程相互干扰。 - 另一方面,JPA 文档说注入的
EntityManager
只是一个代理:它运行的实际 持久性上下文 是绑定到JTA 事务。这样一切都应该没问题,因为即使 EntityManagers 是 "shared",每个 MDB 都会有不同的事务正在进行,因此可以安全隔离地工作。
什么是正确的场景?我错过了什么吗?
以您描述的方式注入无状态 EJB 的实体管理器正是您应该做的。 这种类型的注入提供了 'Container-Managed Entity Manager' 即 'transaction scoped'。 所以在你描述的场景中。
- onMessage MDB 调用将创建一个事务
- 对无状态 bean 的调用将发生在相同的事务上下文中,创建一个实体管理器,该管理器通常在 MDB 方法 returns. 时一直存在到事务完成为止
同一 EJB 实例的特定类型的注入实体管理器不会存在,并且不会在不同的事务中重复使用。