我試圖使用ActiveRecord的find_or_create_by_*column*
,但我從Postgres得到的錯誤讓我知道它偶爾無法找到模型,並試圖插入一個反正。保持這張表的獨特性非常重要,所以我在其遷移中添加了:unique => true
屬性,以便Postgres知道我對此很認真。find_or_create競爭條件
而且,失敗:
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
失敗,除了某種我無法想象的競爭條件。
(請忽略 '用戶' 與 '人' 共享一個主鍵的horribleness) (使用Rails 2.3.11,Postgres的9.0.3)
在編輯我的應用程序的東西,觸發user.save是不是真的實用,我很欣賞的好建議挽救StatementInvalid錯誤並添加有限重試循環。我在'find_or_create'調用中添加了這樣的異常處理。乾杯! – nessur 2011-05-09 17:13:21
在我的應用程序中,模型。ave是由控制器觸發的,所以它很容易包裝在開始救援中。事實上,我在需要這個 – 2011-05-09 18:14:20
P.S的模型中添加了一個名爲save_with_retries(retry_count = 5)的方法。我刪除了user.save中的Transaction,因爲ActiveRecord(根據事務文檔)已經包裝了save,save!並破壞內部交易。 – 2011-05-09 18:16:08