gpt4 book ai didi

ruby-on-rails - find_or_create 竞争条件

转载 作者:行者123 更新时间:2023-12-04 15:03:47 27 4
gpt4 key购买 nike

我正在尝试使用 ActiveRecord 的 find_or_create_by_*column* ,但我从 Postgres 收到错误,让我知道它偶尔无法找到模型,并尝试插入模型。保持这张表的唯一性非常重要,所以我添加了 :unique => true归因于它的迁移,这样 Postgres 就会知道我是认真的。

并且,失败:
ActiveRecord::StatementInvalid: PGError: ERROR: duplicate key value violates unique constraint "index_marketo_leads_on_person_id" DETAIL: Key (person_id)=(9968932) already exists. : INSERT INTO "marketo_leads" ("mkt_person_id", "synced_at", "person_updated_at", "person_id") VALUES(NULL, NULL, '2011-05-06 12:57:02.447018', 9968932) RETURNING "id"
我有这样的模型:

class User < AR::Base
has_one :marketo_lead

before_save :update_marketo_lead

def update_marketo_lead
if marketo_lead
if (User.marketo_columns & self.changes.keys).any?
marketo_lead.touch(:person_updated_at)
end
elsif self.id
marketo_lead = MarketoLead.find_or_create_by_person_id(:person_updated_at => Time.now, :person_id => self.id)
end
end
end

class MarketoLead
belongs_to :user, :foreign_key => 'person_id'
end

第二个模型用于将我们的用户帐户链接到 Marketo 电子邮件服务器,并记录上次修改用户某些字段的时间,以便我们可以在批处理后台任务中推送更改的记录。

我想不出这个回调的任何原因, update_marketo_lead失败,除了某种我无法想象的竞争条件。

(请忽略“用户”与“人”共享主键的可怕性)
(使用 Rails 2.3.11,Postgres 9.0.3)

最佳答案

很可能在执行 find_or_create 时,找不到匹配的 person_id,因此使用了创建逻辑,但是可能在 find_or_create 和实际 user.save 之间,另一个请求设法完成了保存事务,此时您的数据库约束导致了此异常.

我建议的是捕获 StatementInvalid 异常并重试保存(最多有限次......

begin
user.save!
rescue ActiveRecord::StatementInvalid => error
@save_retry_count = (@save_retry_count || 5)
retry if( (@save_retry_count -= 1) > 0 )
raise error
end

请注意,这应该在您尝试保存用户的任何地方执行。所有回调和验证都在保存中发生!交易

附言我假设您的 Rails 版本支持事务:) 在 Rails 3 中,不需要包装保存!在交易中,因为它已经在内部使用了一个

关于ruby-on-rails - find_or_create 竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5917355/

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