【问题标题】:Is it possible to persist/merge entities in parallel, in a single transaction, using JavaEE 7?是否可以使用 JavaEE 7 在单个事务中并行持久化/合并实体?
【发布时间】:2018-06-23 05:24:48
【问题描述】:

假设我有一个 EJB,即 CrudService,它具有在单个实体(而不是集合)上执行 CRUD 的方法。 CrudService 有一个 EntityManager 注入其中,不能修改。 CrudService 看起来像这样:

@Stateless
public class CrudService {

  @PersistenceContext(name = "TxTestPU")
  private EntityManager em;

  public Integer createPost(Post post) {
     post = em.merge(post);
     return post.getId();
  }

  public void updatePost(Post post) {
      em.merge(post);        
  }

  public Post readPost(Integer id) {
      return em.find(Post.class, id);
  }

  public void deletePost(Post post) {
      em.remove(post);
  }
}

我希望能够在单个事务中并行创建/更新 Post 实体的集合。一种不起作用的方法是,对于池中的每个线程,容器都会创建一个新事务,如下所示:

@Stateless
public class BusinessBean {

  @Inject
  private CrudService crudService;

  public void savePosts(Collection<Post> posts) {
      posts.parallelStream().forEach(post ->
          crudService.createPost(post);
  }
}

有办法吗? 代码在 Wildfly 上运行,带有 Hibernate 持久性单元和 Postgresql 数据库。

【问题讨论】:

  • 这可能不起作用,因为运行子任务的池线程将没有正确的上下文。此外,流库是为 数据并行 而设计的,而不是 IO 并行。因此,您也不太可能获得您认为会获得的并行性。
  • 感谢您的意见!事实上,流正是我打算并行化工作的方式。这里的主要目标是在单个事务中并行执行插入,不一定使用流。也改了标题。

标签: jpa java-8 jpa-2.0 ejb-3.1 java-ee-7


【解决方案1】:

直截了当的“这是一个答案”的答案。

不是一般的。看看这个问题的答案:Is it discouraged using Java 8 parallel streams inside a Java EE container?


烦人的“XY problem”答案。

您认为这会如何运作?大多数数据库不支持单个数据库连接上的多个并行事务,我不相信 PG 支持它:https://stackoverflow.com/a/289057/924597

所以某些东西/某人(JEE 容器、JDBC、驱动程序等)必须打开多个数据库连接才能实现这一点——我想你说的是发生了什么?如果您在许多不同的业务操作中执行此操作,这可能会很快耗尽您的连接池。

本着这是一个“XY 问题”答案的精神 - 您要解决什么问题?

如果这只是一个原始吞吐量问题 - 考虑批量插入。

如果是批量插入问题 - 考虑在容器周围进行末端运行并使用不同的工具,JEE 容器通常不适合/不擅长这种事情。

【讨论】:

  • 问题确实出在吞吐量上。我也考虑过插入批处理,但集合大小各不相同,我无法直接访问 PU 定义。这就是为什么我要从 CrudService 的“外部”寻找解决方案的原因。是的,目前来自分叉连接池的每个线程都获得一些处理实体集合的工作,都有自己的数据库事务。
  • @cristian3181763 关于“我无法直接访问 PU 定义”。如果您确实有必须处理的吞吐量问题 - 忘记 PU 并直接使用 JDBC 数据源或连接。考虑根据您的潜在问题提出一个新问题。并行化您的解决方案可能是正确的方法 - 但使用流并行化事务可能会导致错误的树。
  • 感谢您的意见! Streams 只是拆分工作的一种快速方法。我可能使用了其他方法。该问题与流无关,而是与在同一个事务中并行地持久化大量实体集合有关。
猜你喜欢
  • 2012-06-17
  • 2012-11-14
  • 2010-12-30
  • 2010-10-26
  • 2012-05-19
  • 2015-04-24
  • 2011-12-22
  • 1970-01-01
  • 2015-11-15
相关资源
最近更新 更多