предотвращение вставки дубликатов несколькими активными процессами записи - PullRequest
1 голос
/ 27 августа 2010
class State < ActiveRecord::Base
  validates_uniqueness_of :identifier
end

Теперь предположим, что есть два запущенных процесса, которые могут одновременно вставить две из этих записей. Пассажир - хороший пример. Вот надуманный:

State.find_by_identifier("UNIQ").delete rescue nil
while Time.now < Time.now.change(:hour => 17, :min => 00, :sec => 15)
  sleep 0.001
end
ActiveRecord::Base.transaction do
  s = State.new;s.identifier = "UNIQ"
  s.save!
end
s.valid?

Идея состоит в том, что мы изменяем значения времени, чтобы быть немного в будущем. Затем скопируйте / вставьте все это в две разные консоли.

Конечная цель - заставить их «отпустить» одновременно. Что просходит? Им обоим удается создать новый объект State, и они оба возвращают false в конце.

Так, как я могу предотвратить это?

Для чего я стою, я использую MySQL, а таблица InnoDB.

1 Ответ

0 голосов
/ 27 августа 2010

Вы используете #find_or_create вспомогательные методы, в дополнение к правильной проверке и уникальному индексу на уровне базы данных:

# In a migration
add_index :states, :identifier, :unique => true

class State < ActiveRecord::Base
  validates_uniqueness_of :identifier
end

State.find_or_create_by_identifier("UNIQ")

Это будет работать с любым адаптером.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...