Эта строка:
self.class.find(:all,:order=>"shortcode ASC").each
выполнит последовательный поиск по всей вашей коллекции записей. Вам придется заблокировать всю таблицу, чтобы, когда один из ваших процессов сканировал следующее целое число, другие ожидали завершения первого. Это будет убийца производительности. Мое предложение, если это возможно, заключается в следующем:
- Добавить столбец, который указывает, когда истек срок действия записи (срок действия истекает к моменту создания? Последнее использование?). Индексируйте этот столбец.
Когда вам нужно найти следующий наименьший используемый номер, сделайте что-то вроде
Shorts.find (: condition => {: expired => true} ,: order => 'shortcode')
У базы данных будет сложная работа по поиску шорткода с наименьшим сроком действия. Напомним, что в отсутствие параметра : all метод find возвращает только первую соответствующую запись.
Теперь, чтобы предотвратить состязание между процессами, вы можете заключить это в транзакцию и заблокировать во время поиска:
Shorts.transaction do
Shorts.find(:conditions => {:expired => true},:order => 'shortcode', :lock => true)
#Do your thing here. Be quick about it, the row is locked while you work.
end #on ending the transaction the lock is released
Теперь, когда второй процесс начинает искать бесплатный шорткод, он не читает тот, который заблокирован (так что, вероятно, он найдет следующий). Это связано с тем, что параметр: lock => true получает эксклюзивную блокировку (для чтения и записи).
Проверьте это руководство , чтобы узнать больше о блокировке с помощью ActiveRecord.