当前位置: 首页 > 面试题库 >

使用多个线程的JPA持久性

楚畅
2023-03-14
问题内容

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

细节 :

假设我有一个对象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_GROUPS和中创建条目CREDIT_TRANSFERS

我如何解决这个问题,同时维护拆分主付款顺序使用组逻辑和多个线程?


问题答案:

你有选择。
1)原始但简单,最后捕获密钥冲突错误,然后在没有父母的情况下重试插入。假设您的父母确实是独一无二的,您就会知道父母刚刚采取了另一种措施……带着孩子。与其他选项相比,这可能效果不佳,但也许您会得到所需的流行音乐。如果您的父母中有一个孩子的父母百分比很高,则效果很好。

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

3)用单线程使用者实现工作队列。如果程序的主要昂贵工作在持久性级别之前,则可以让线程将其数据“插入”到工作队列中,在其中不执行键。然后从工作队列中拉出一个线程并继续执行。工作队列可以在内存中,在另一个表中或在供应商特定的位置(Weblogic
Queue,Oracle
AQ等)。如果程序的主要工作在持久性之前,则对THAT进行并行处理,然后返回到插入上的单个线程。您甚至可以使消费者在“批量插入”模式下工作。Sweeeeeeeet。

4)放松约束。谁真正在乎同一个孩子是否有两个父母持有相同的信息?我只是问问。如果以后您不需要父信​​息的超快速更新,并且可以更改阅读程序以了解它,那么它可以很好地工作。在数据库设计课程中,它不会使您获得“
A”,但如果可以的话…

5)实现一个愚蠢的锁表。我讨厌这个解决方案,但是它确实有效—让您的线程写下它正在父级“
x”上工作,并且没有其他人可以作为它的第一个事务(和提交)。通常会导致相同的问题(以及其他问题–稍后清除记录等),但是在子插入速度较慢而单行插入速度较快时也可以使用。您仍然会有碰撞,但是碰撞更少。



 类似资料:
  • 谢谢 ----更新----

  • 有没有办法将quarkus security jpa与多个持久性单元一起使用?JpaIdentityProvider似乎直接注入了实体管理器工厂,这导致了“javax.persistence.EntityManagerFactory类型的不满意依赖”的异常。 可能有解决办法吗? 有什么建议吗? 谢谢文森特

  • 我有一个应用程序,它使用位于两个不同数据库中的一组JPA实体。我配置了多个持久性单元。 问题是我想使用模式生成自动生成模式,所有实体都是在两个数据库中创建的。 我在这两方面都有: 是的,我想使用元数据自动获取实体。我不想提供手动脚本,因为我需要使它与实体保持最新。 是否有方法标记由哪个PU生成的实体? 编辑:请注意,在@Table上添加“模式”属性并不能解决问题,因为每个PU将尝试在正确的模式中创

  • 问题内容: 我需要使用一个数据库进行查询(非修改),而使用一个数据库进行命令(修改)。我正在使用Spring Data JPA,所以我有两个配置类: 在我的存储库中,有时我需要决定与EntityManager一起使用,如下所示: 我使用在我的定义持久性单元的名称 的persistence.xml : 定义了弹簧抛出。奇怪的是,看起来Spring尝试使用持久性单元名称实例化 bean ?我配置错误了

  • 这就是我的datasourcebean的样子

  • 最后的修正:由于Vlad的回答,我能够更新代码以使用以下内容(只需确保您还定义了bean):