I'm encountering an unexpected situation with finding/creating particular records in the following table during periods of high contention. I believe there is a race condition in the database.
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
Offending code:
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
The find in the find_or_create_by!
returns nil and triggers the create!
which raises a ActiveRecord::RecordNotUnique
error. The rescue block catches it and attempts to find the record which caused the not unique error but it also returns nil. My expectation is that if the index uniqueness constraint is violated than the record should be committed to the table. What am I missing?
Aucun commentaire:
Enregistrer un commentaire