Рельсы 3 - Потенциальное состояние гонки? - PullRequest
1 голос
/ 21 июля 2011

У меня есть действительно простое приложение на Rails 3, где пользователи могут зарезервировать один из конечного числа однородных элементов на определенный день.Я пытаюсь избежать состояния гонки, когда два человека оставляют за собой последний предмет, доступный в определенный день.Модель (упрощенная) выглядит следующим образом:

class Reservation < ActiveRecord::Base
  belongs_to :user
  attr_accessible :date
  MAX_THINGS_AVAILABLE = 20

  validate :check_things_available

  def check_things_available
    unless things_available? errors[:base] << "No things available"
  end

  def things_available?
    Reservation.find_all_by_date(date).count < MAX_THINGS_AVAILABLE 
  end           
end

Резервирование создается в контроллере с помощью current_user.reservations.build(params[:reservation])

Такое ощущение, что есть лучший способ сделать это, но яне могу понять, что это такое.Буду очень признателен за любую помощь в предотвращении гонки.

Ответы [ 2 ]

0 голосов
/ 15 августа 2013

Просто используйте любой механизм блокировки, например Redis Locker

RedisLocker.new("thing_to_sell_#{@thing.id}").run do
  current_user.create_reservation(@thing) or raise "Item already sold to another user"
end
0 голосов
/ 27 сентября 2011

Не уверен, что это отвечает на ваш вопрос, но может указывать на решение:

http://webcache.googleusercontent.com/search?q=cache:http://barelyenough.org/blog/2007/11/activerecord-race-conditions/

(кажется, что оригинальный сайт не работает, так что это ссылка на кеш Google)

Вывод на этой странице заключается в том, что оптимистическая блокировка и блокировка на уровне строк не являются решениями для условий гонки при создании, а только при обновлении.

Автор предлагает переопределить find_or_create с ограничением db.

Другое предложение заключается в том, что переключение уровня изоляции транзакций на «сериализуемый» должно работать, но нет информации о том, как это сделать в Rails.

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