java - 使用多线程的JPA持久化

标签 java multithreading hibernate orm jpa-2.0

当我尝试使用多线程保留对象时遇到问题。

详细信息:

假设我有一个对象 PaymentOrder其中有一个列表 PaymentGroup (一对多关系)和 PaymentGroup包含 CreditTransfer 的列表(再次是一对多关系)。

自数量CreditTransfer很大(十万),我根据 PaymentGroup 对它进行分组(基于一些业务逻辑) 并创建 WORKER 线程(每个 PaymentGroup 一个线程)以形成 PaymentOrder对象并提交到数据库中。

问题是,每个工作线程都创建一个PaymentOrder (其中包含一组唯一的 PaymentGroup )。

所有实体的主键都是自动生成的。

所以有三个表,1. PAYMENT_ORDER_MASTER、2. PAYMENT_GROUPS、3. CREDIT_TRANSFERS,都是通过一对多关系映射的。

因为当第二个线程尝试将其组保留在数据库中时,框架会尝试保留相同的 PaymentOrder ,前一个线程提交,事务由于一些其他唯一字段约束( PaymentOrder 的校验和)而失败。

理想情况下,它必须是 1..n..m ( PaymentOrder ->PaymentGroup --> CreditTransfer`)

我需要实现的是如果没有PaymentOrder的条目在数据库中输入一个条目,如果有,则不要在 PAYMENT_ORDER_MASTER 中输入条目,但仅限于PAYMENT_GROUPSCREDIT_TRANSFERS .

如何解决这个问题,维护 split-master- payment-order-using-groups 逻辑和多线程?

最佳答案

您有多种选择。
1)原始但简单,在最后捕获关键违规错误并在没有 parent 的情况下重试插入。假设你的 parent 确实是独一无二的,你知道另一个线程只是让 parent ……继续照顾 child 。与其他选项相比,这可能表现不佳,但也许您会得到所需的流行。如果您有一个 child 的 parent 比例较高,那么效果会很好。

2) 更改读取一致性级别。它是特定于供应商的,但有时您可以读取未提交的事务。这将帮助您在提交之前查看其他线程的工作。这并不是万无一失的,你仍然必须执行#1,因为另一个线程可以在读取后潜入。但它可能会提高您的吞吐量,但代价是更加复杂。基于 RDBMS 可能是不可能的(或者也许它可能发生,但仅在数据库级别,弄乱其他应用程序!)

3) 使用单线程消费者实现工作队列。如果程序的主要昂贵工作是在持久性级别之前,您可以让线程将其数据“插入”到工作队列中,其中不强制执行键。然后从工作队列中提取一个线程并保留。工作队列可以位于内存中、另一个表中或供应商特定的位置(Weblogic 队列、Oracle AQ 等)。如果程序的主要工作是在持久化之前,那么您可以并行化它并返回到插入上的单个线程。您甚至可以让您的消费者在“批量插入”模式下工作。亲爱的。

4)放松你的限制。谁真正关心同一个 child 的两个 parent 是否持有相同的信息?我只是问问。如果您以后不需要对家长信息进行超快速更新,并且可以更改阅读程序来理解它,那么它可以很好地工作。它不会让你在数据库设计课上获得“A”,但如果它有效......

5) 实现一个愚蠢的锁表。我讨厌这个解决方案,但它确实有效——让你的线程写下它正在父“x”上工作,而其他人不能,因为它是第一个事务(和提交)。通常会导致相同的问题(以及其他问题 - 稍后清理记录等),但在子插入速度慢而单行插入速度快时可以工作。您仍然会遇到冲突,但会减少。

关于java - 使用多线程的JPA持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6514117/

相关文章:

java - 自定义 JOptionPane 图标

java - 如何解决此错误消息以创建 Enum : "Project ' MyFunProject' is not a J2SE 5. 0 兼容项目。”

c++ - 同步此事件实现的最佳方式是什么

Java多线程应用程序只使用一个核心

java - Java 线程(大学练习)

java - JPA:保留/更新子项期间的事件通知?

java - 如何从套接字而不是内容接收文件?

java - GIJ(Java 的 GNU 解释器)是否足够稳定以用于商业用途?

java - Hibernate session.update() 与更新查询?

java - 带有 JPA 的 AEM CQ( hibernate )