gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 12:57:10 41 4
gpt4 key购买 nike

当我尝试使用 持久化对象时遇到问题多线程 .

详情:

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

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

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

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

所以一共有三个表,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 ......继续与 children 相处。与其他选项相比,这可能表现不佳,但也许您会获得所需的流行音乐。如果您有一个 child 的 parent 比例很高,那效果会很好。

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

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

4)放宽你的限制。如果同一个 child 有两个 parent 持有相同的信息,谁在乎呢?我只是问问。如果您以后不需要父信​​息的超快速更新,并且您可以更改您的阅读程序以理解它,它可以很好地工作。它不会让你在 DB 设计类(class)中获得“A”,但如果它有效......

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

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

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com