@OnetoOne Cascade在Eclipselink中执行多个更新覆盖了DB中存在的更新值

发布于 2025-01-26 05:52:29 字数 776 浏览 2 评论 0 原文

以下是parent表DTO,它的请求status为in_progress,在更新子表时已更新到以下:下面:

@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="vendor", targetEntity=StatusDTO.class)
    private IStatus serviceabilityStatus;

@Column(name="REQUEST_STATUS", length=15)
    private String requestStatus;

下面是子表dto,插入和更新request requestStatus to在Parent Tabt dto中完成

@OneToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER,targetEntity=VendorDTO.class)
    @JoinColumn(name="SERVICEABILITY_KEY", unique=true)
    private IVendor vendor;

我们在运行100个产品时检查,用于使用100个产品,用于每个产品保存在保存子表时,它会更新父表RequestStatus,并再次从另一个线程更新为IN_Progress。因此,最终状态大约在100个中,大约有50个标记为已完成,并保留为Inprogress。

我们尝试使用冲洗和清晰的EntityManager,但问题仍然存在。

Below is the parent table dto which has requestStatus as IN_PROGRESS which gets updated to DONE on updating child table as below:

@OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="vendor", targetEntity=StatusDTO.class)
    private IStatus serviceabilityStatus;

@Column(name="REQUEST_STATUS", length=15)
    private String requestStatus;

Below is the child table dto which insert record and update requestStatus to DONE in parent table dto

@OneToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE},fetch=FetchType.EAGER,targetEntity=VendorDTO.class)
    @JoinColumn(name="SERVICEABILITY_KEY", unique=true)
    private IVendor vendor;

We checked when running for 100 products, for each product while saving child table, it updates parent table requestStatus to Done and again it updates to IN_PROGRESS from another thread. So, final status is like out of 100, around 50 are marked as Done and remaining as InProgress.

We tried using flush and clear entitymanager but issue still persist.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

李不 2025-02-02 05:52:29

同时修改多个过程中相同数据的应用程序绑定到彼此覆盖。数据库提供悲观的锁定,允许操作锁定一行,直到有机会修改它,以防止任何人在此过程中将其从中脱颖而出,但这只是皱眉并仅作为最后的手段,因为它很昂贵且难以实现管理,需要更多的陈述才能获取锁,然后剩下的流程等待才能获得。

相反,通常要做的是乐观的锁定。这允许无需等待即可读取数据。在写下该版本已被检查和增加,如果不是预期的话,则会发生异常。自从您上次读取数据以来,这允许检测何时更新数据。您的过程需要捕获例外,重新阅读/刷新数据,并在必要时重试。这是乐观的,因为它是事实检查之后。乐观的假设是,当它发生时处理较低,然后悲观地锁定一切以防止一切。

See https://en.wikibooks.org/wiki/Java_Persistence/Locking#Optimistic_Locking https://wwwww.baeldung.com/jpa-optimistic-locking-locking-locking and 有关该主题的讨论。

您的应用程序还将合并从孩子到其参考父母的合并,增加了陈旧数据覆盖的风险;例如,如果一个过程仅取决于并仅打算更新子女条目,则在父母中合并并增加了可能是陈旧的风险。仅影响儿童数据的过程只能在儿童实例中合并,因此请仔细选择您的级联选择。

版本锁定需要对象中可以将某种形式的版本字段进行递增或向前移动,但是还有其他选项。 Eclipselink具有许多字段锁定选项,可以检查更改的字段,所有字段,甚至选择性的字段,甚至选择性为数据库中的字段。参见有关详细信息

Apps that concurrently modify the same data in multiple processes are bound to overwrite each other. Database offer pessimistic locking, allowing operations to lock a row until it gets a chance to modify it, preventing anyone from changing it out from under the process, but this is frowned upon and used only as a last resort as it is expensive and difficult to manage, requiring more statements to obtain locks, and processes left waiting until they obtain them.

What instead is usually done is optimistic locking. This allows data to be read in without waiting. On writes the version is checked and incremented, and an exception occurs if it isn't what is expected. This allows detecting when another process has updated the data since you last read it. Your process would need to catch the exception, re-read/refresh its data and try again if necessary. This is optimistic because it is an after the fact check; optimistic in its assumption that it is less expensive to deal with when it occurs then to pessimistically lock everything to prevent.

See https://en.wikibooks.org/wiki/Java_Persistence/Locking#Optimistic_Locking, https://www.baeldung.com/jpa-optimistic-locking and https://www.eclipse.org/eclipselink/documentation/2.6/concepts/cache004.htm for discussions on the topic.

Your application is also cascading the merge from child to its reference parent, increasing the risk of the stale data overwrites; for instance, if a process is only dependent upon and only intends to update a child entry, merging in the parent as well increases the risk that it might be stale. A process that only affects a child data should only merge in the child instance, so choose your cascade options on relationships carefully.

Version locking requires some form of version field in the object that can be incremented or moved forward, but there are other options. EclipseLink has a number of field locking options that can have it check the changed fields, all fields or even selective ones against what is in the database. See https://www.eclipse.org/eclipselink/documentation/2.7/concepts/descriptors002.htm#CIHCFEIB for details

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文