在高争用期间,我遇到了在下表中查找/创建特定记录的意外情况。我相信数据库中存在竞争条件。不寻常的ActiveRecord行为
create_table "business_objects", force: :cascade do |t|
t.string "obj_id", limit: 255
t.string "obj_type", limit: 255
t.datetime "created_at", precision: 6, null: false
end
add_index "business_objects", ["obj_type", "obj_id"], name: "index_business_objects_on_obj_type_and_obj_id", unique: true, using: :btree
违规代码:
def find_or_create_this
attributes = self.attributes.slice('obj_id', 'obj_type')
BusinessObject.find_or_create_by!(attributes)
rescue ActiveRecord::RecordNotUnique
BusinessObject.find_by!(attributes)
end
的发现在find_or_create_by!
返回nil并触发这引起了一个ActiveRecord::RecordNotUnique
错误create!
。救援块捕获它并试图找到导致不唯一错误的记录,但它也返回nil。我的期望是,如果索引唯一性约束被违反,则应该将该记录提交给表。我错过了什么?