我正在尝试使用ActiveRecord的find_or_create_by_ *列*,但是我从Postgres得到错误让我知道它偶尔找不到模型,并试图插入一个.我保持这个表的独特性非常重要,所以我添加了一个:unique =>这是其迁移的真正属性,因此Postgres会知道我对此很认真.
并且,失败:
ActiveRecord :: StatementInvalid:PGError:ERROR:重复键值违反唯一约束“index_marketo_leads_on_person_id”DETAIL:键(person_id)=(9968932)已存在. :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)返回“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,因此使用了create logic,但是它可能在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
请注意,这应该在您尝试保存用户的任何位置执行.所有回调和验证都在保存中发生!交易
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。