競合が激しい時期に、次の表に特定のレコードを見つけたり作成したりすることで予期せぬ状況に遭遇しました。私はデータベースに競合状態があると信じています。珍しい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!
返すゼロで見つけるとActiveRecord::RecordNotUnique
エラーが発生create!
をトリガします。レスキューブロックはそれをキャッチし、一意でないエラーを引き起こしたレコードを見つけようとするが、nilも返す。私の期待は、レコードがテーブルにコミットされるよりもインデックスの一意性制約が違反された場合です。私は何が欠けていますか?