gpt4 book ai didi

hibernate - Hibernate写冲突

转载 作者:行者123 更新时间:2023-12-02 14:44:34 24 4
gpt4 key购买 nike

我在MySQL上使用Grails 1.3.7。我的应用程序服务器记录用户运行的查询的搜索结果。模式(简化)包括

class Query {
String query
String user
}

class Document {
String externalId
String title
}

class Posting {
Query query
Document document
int rank
}

每当用户第一次运行查询以检索文档时,我都会创建一个新实例;否则,在创建相应的 Posting实例时,我将重用现有实例。对于给定的 Document,应仅存在一个 externalId实例,但是可以有多个 Posting实例指向该实例。

多个用户可以运行查询来检索相同的文档,但是这会导致并发问题。如果两个用户大约在同一时间第一次检索同一文档,则第二次创建 Document的尝试将失败,并且对 externalId的唯一约束违反。很好不好的是,与重复的 Posting关联的新创建的 Document实例也将被回滚。这不好,因为很难指出如何重试保存。

我想出的解决方案是通过使用调用 Document的同步方法来创建 save(flush: true),如果失败,则从数据库中重新读取文档。然后将生成的文档(无论是保存还是重新读取)用于填充 Posting实例。此解决方案有效,但是处理用户检索到的结果太慢。如果我摆脱了 flush: true参数,性能会提高,但是我不能保证会正确创建 DocumentPosting实例。

什么是实施此类更新的正确方法?

澄清说明

我正在运行的查询一次返回100个匹配项,这意味着我将为每个用户请求创建0-100个 Document实例和100个 Posting实例。

最佳答案

我可能没有完全理解这个问题,因此听起来有些天真。你不能用optimistic locking解决这个问题吗?

在您的catch块中,假设第二个用户是参加聚会的那个人,那么您是否不能拉出文档的最新版本并分配给第二个用户的发帖。

try {
def posting = ....
posting.save(flush: true)
}
catch (org.springframework.dao.OptimisticLockingFailureException e) {
def doc = Document.findByExternalId(posting.document.externalId)
posting.document = doc
posting.save(flush: true)
...
}

关于hibernate - Hibernate写冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17156510/

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