mysql - 异常的 ActiveRecord 行为

标签 mysql ruby ruby-on-rails-3 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 错误。救援 block 捕获它并尝试找到导致非唯一错误的记录,但它也返回 nil。我的期望是,如果违反索引唯一性约束,则应将记录提交给表。我错过了什么?

最佳答案

要回答我自己的问题,请研究 MySQL 的事务隔离级别.将有问题的代码包装在事务 block 中并修改隔离级别。

选项是:

  1. 阅读未提交
  2. 可序列化
  3. 可重复读
  4. 已提交阅读

    def find_or_create_this attributes = self.attributes.slice('obj_id', 'obj_type') ActiveRecord::Base.transaction(isolation: :read_committed) 做 BusinessObject.find_or_create_by!(属性) 结尾 救援 ActiveRecord::RecordNotUnique ActiveRecord::Base.transaction(isolation: :read_committed) 做 BusinessObject.find_by!(属性) 结尾 结束

关于mysql - 异常的 ActiveRecord 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40599861/

相关文章:

ruby-on-rails - Ruby on Rails 实例与类方法

html - 如何允许用户在 Rails 中提交自定义电子邮件模板?

ruby-on-rails - Rails 迁移 - self.up 和 self.down 有什么意义

mysql - PhpMyAdmin 数据库莫名其妙消失了

mysql - 如何在 Laravel ORM 中为每个组中的单个项目执行 groupBy()

phpMyAdmin - 不将 MySQL 查询读取为数字

javascript - 如何在 Rails 中使用 gmaps

MySQL CREATE USER 带有变量?

ruby - 在 Heroku Cedar 上的 Rails 3.2 中,是否有一种标准的方式来提供预压缩的 Assets ?

javascript - 如何自动将JS文件放入AJAX调用的页面中?