Я создаю приложение на основе Sinatra для развертывания на Heroku. Вы можете представить себе это как стандартный сократитель URL-адресов, но где старые короткие коды истекают и становятся доступными для новых URL-адресов (я понимаю, что это глупая концепция, но ее проще объяснить). Я представляю короткий код в моей базе данных как целое число и переопределяю его читатель, чтобы получить красивую короткую и уникальную строку из целого числа.Блокировка базы данных: ActiveRecord + Heroku
Поскольку некоторые строки будут удалены, я написал код, который проходит через все цепочки коротких номеров и выбирает первый бесплатный, который можно использовать только before_save
. К сожалению, я могу сделать свой код для создания двух строк с одинаковыми целыми числами shortcode, если я запускаю два экземпляра очень быстро один за другим, что явно не хорошо! Как мне реализовать систему блокировки, чтобы я мог быстро сохранить свою запись с уникальным целым числом коротких номеров?
Вот что я до сих пор:
Chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
CharLength = Chars.length
class Shorts < ActiveRecord::Base
before_save :gen_shortcode
after_save :done_shortcode
def shortcode
i = read_attribute(:shortcode).to_i
return '0' if i == 0
s = ''
while i > 0
s << Chars[i.modulo(CharLength)]
i /= 62
end
s
end
private
def gen_shortcode
shortcode = 0
self.class.find(:all,:order=>"shortcode ASC").each do |s|
if s.read_attribute(:shortcode).to_i != shortcode
# Begin locking?
break
end
shortcode += 1
end
write_attribute(:shortcode,shortcode)
end
def done_shortcode
# End Locking?
end
end