我尝试使用 多个线程 持久化对象时遇到问题。
细节 :
假设我有一个对象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):