java - 结合 MDB、JPA 和 JTA

标签 java jpa jta message-driven-bean

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

  • 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)提供了“事务范围”的“容器管理实体管理器”。 所以在你描述的场景中。

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

同一 EJB 实例的特定类型的注入(inject)实体管理器无法保留,并且不会在不同事务中重复使用。

关于java - 结合 MDB、JPA 和 JTA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51650280/

相关文章:

java - 在 Java 中使用泛型为类编写什么单元测试?

spring-boot - 与axon连接的微服务是否应该共享axon框架相关表?

java - 如何使用 hibernate 设置 UserTransaction

java - 具有内部类的变量作用域

java - 替换文件中字符串中的确切字符?

java - 多个JAVA JDK启动Elasticsearch服务的方法

spring - 如何在 JUnit 测试中模拟 TransactionManager(在容器外)?

java - JSP 在开普勒 (Eclipse Standard 4.3) 中以黑白方式打开

java - 由于@OneToMany,JPA 更新记录失败

spring - 使用 Atomikos 进行两阶段提交 (2PC) 配置