【发布时间】:2015-04-22 17:59:07
【问题描述】:
我正在使用一个 Rails 4 应用程序,该应用程序需要创建大量对象以响应来自另一个系统的事件。当我在我的一个模型上调用create! 时,我在主键列上出现了非常频繁的ActiveRecord::RecordNotUnique 错误(由PG::UniqueViolation 引起)。
我在 SO 上找到了其他建议抢救异常并调用 retry 的答案:
begin
TableName.create!(data: 'here')
rescue ActiveRecord::RecordNotUnique => e
if e.message.include? '_pkey' # Only retry primary key violations
log.warn "Retrying creation: #{e}"
retry
else
raise
end
end
虽然这似乎有帮助,但对于数据库中已经存在的顺序 ID(日志条目缩写),我仍然收到 吨 ActiveRecord::RecordNotUnique 错误:
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3067) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3068) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3069) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3070) already exists.
它尝试的 ID 在 3000-4000 范围内,即使有问题的表中有超过 90000 条记录。
为什么 ActiveRecord 或 PostgreSQL 会浪费大量时间依次尝试现有 ID?
原始异常(简化/删除的查询字符串):
{
"exception": "ActiveRecord::RecordNotUnique",
"message": "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"table_name_pkey\"\nDETAIL: Key (id)=(3023) already exists."
}
【问题讨论】:
标签: sql ruby-on-rails ruby postgresql activerecord