gpt4 book ai didi

java - Hibernate 并发在 saveOrUpdate 上创建重复记录

转载 作者:太空宇宙 更新时间:2023-11-04 11:14:11 25 4
gpt4 key购买 nike

我正在尝试使用 Java、Spring、Hibernate 和 Oracle SQL 实现计数器。每条记录代表一个给定时间戳记的计数。假设每条记录都由分钟唯一标识,并且每条记录都包含一个计数列。该服务应该会收到大量并发请求,并且我会更新可能相同记录的计数器列。

在我的表中,如果该记录不存在,只需插入该记录并将其计数设置为1。否则,通过时间戳查找该记录并将其现有计数器列增加1。

为了确保我们保持数据的一致性和完整性,我使用悲观锁定。例如,如果 20 个计数同时进入,并且不一定来自同一用户,则我们可能会在更新之前从该记录的陈旧读取中覆盖该记录。通过锁定,我可以确保如果有 20 个计数进入,对数据库的净影响应该代表 20 个计数。

所以锁定没问题,但问题是,如果记录从一开始就不存在,并且我们有两个或多个并发请求试图更新尚不存在的记录,我观察到插入了重复的记录,因为我们无法锁定尚不存在的记录。我们如何确保表中不会创建重复项?应该通过Oracle 来控制吗?或者我可以通过我的应用程序和 Hibernate 来管理它吗?

谢谢。

最佳答案

要完全避免此类问题,一种方法是在实际查询数据时生成计数。 Oracle 有一个分析函数ROW_NUMBER(),它可以为查询结果集中的每条记录分配行号。作为一个粗略的示例,请考虑以下查询:

SELECT
ts,
ROW_NUMBER() OVER (ORDER BY ts) rn
FROM yourTable

您想要的计数将位于 rn 列中,表示自表中第一个条目以来出现的记录数。当然,您可以进一步限制查询。

这种方法对于删除记录非常有效,因为计数始终从 1 开始。一个缺点是 Hibernate 不支持行号功能。您必须将其作为 native 查询或存储过程运行。

关于java - Hibernate 并发在 saveOrUpdate 上创建重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45668196/

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