Я столкнулся с непредвиденной ситуацией с поиском/созданием конкретных записей в следующей таблице в периоды высокой конкуренции. Я считаю, что в базе данных есть состояние гонки.Необычное поведение 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 и запускает create!
, который вызывает ошибку ActiveRecord::RecordNotUnique
. Блок спасения улавливает его и пытается найти запись, которая вызвала не уникальную ошибку, но также возвращает ноль. Мое предположение заключается в том, что если ограничение уникальности индекса нарушено, то запись должна быть привязана к таблице. Что мне не хватает?