ruby-on-railsruby-on-rails-4duplicate-datamodel-validationcpu-load

Rails model scoped uniqueness validation unexpectedly skipped in high CPU load


I realized that Rails scoped validation sometimes skipped unexpectedly which results in duplicated record. As a notice, my server is doing some high CPU tasks which regularly fills 80-100% of 6 CPU cores.

Is my validation setting incorrect, or does Rails has a possibility to insert duplicated records in the case of high load environment?

class User < ActiveRecord::Base
  has_many :messages
end

class Message < ActiveRecord::Base
  belongs_to :user
  validates :message, presence: true, uniqueness: {scope: :user_id}, format: {without: /\s/}
end

Solution

  • Rails has a possibility to insert duplicate records, violating the validation.

    The reason is because Rails performs two queries for a uniqueness validation - one to check that the value is unique, and then if that succeeds, another to insert the new record.

    If another process is doing something and inserts another record in between those two queries, you'll end up with duplicate data in the database. I presume high load means the time between the two queries will be longer, increasing the likelihood of this happening.

    If you really want to ensure uniqueness, do it with a database-level unique index.

    See Ruby on Rails - Uniqueness for more information (but it's not technically a duplicate question).