gpt4 book ai didi

ruby-on-rails - ActiveRecord 的 find_or_create* 方法是否存在根本性缺陷?

转载 作者:数据小太阳 更新时间:2023-10-29 07:12:37 31 4
gpt4 key购买 nike

有几种方法:first_or_create_byfind_or_create_by等,它们的工作原理是:

  1. 与数据库对话以尝试找到我们想要的东西
  2. 如果我们找不到,就自己做
  3. 保存到数据库

显然,并发调用这些方法可能会使两个线程都找不到它们想要的东西,并且在第 3 步中一个线程会意外失败。

似乎更好的解决方案是,创建或查找

即:

  1. 提前在您的数据库中创建合理的唯一性约束。
  2. 如果你想保存一些东西,就保存它
  3. 如果有效,那就太好了。
  4. 如果它因为 RecordNotUnique 异常而无法工作,它已经存在,太好了,加载它

那么在什么情况下我想使用 Rails 内置的东西而不是我自己的(看起来更可靠)create_or_find

最佳答案

在深入研究之后,我将回答我自己的问题。

查找或创建的文档说:

Please note this method is not atomic, it runs first a SELECT, and if there are no results an INSERT is attempted. If there are other threads or processes there is a race condition between both calls and it could be the case that you end up with two similar records.

Whether that is a problem or not depends on the logic of the application, but in the particular case in which rows have a UNIQUE constraint an exception may be raised, just retry:


begin
CreditAccount.find_or_create_by(user_id: user.id)
rescue ActiveRecord::RecordNotUnique
retry
end

这通常比 create_or_find 有更好的性能。

考虑到 create_or_find 在成功的情况下需要 1 次 DB 行程,每个唯一记录只会发生一次。每隔一次,它将需要 2 次数据库访问(失败的创建和搜索)。

在失败的情况下重试 find_or_create 将需要 3 次(搜索、创建失败、再次搜索),但这只能在非常小的窗口内发生这么多次。除此之外,每一次调用都将find_or_create 一条记录,将需要 1 次 DB 行程。

因此,重试 find_or_create 的摊销成本更好,并且可以快速达到。

关于ruby-on-rails - ActiveRecord 的 find_or_create* 方法是否存在根本性缺陷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43546779/

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