开发者

Rails 3 - Potential Race Condition?

I have a really simple Rails 3 application where users can reserve one of a finite number of homogeneous items for a particular day. I'm trying to avoid a race condition where two people reserve the last item available on a particular day. The model (simplified) is as follows:

class Reservation < ActiveRecord::Base
  belongs_to :user
  attr_accessible :date
  MAX_TH开发者_运维百科INGS_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

The reservation is being created in the controller via current_user.reservations.build(params[:reservation])

It feels like there is a better way to do this, but I can't quite put my finger on what it is. Any help on how to prevent the race condition would be greatly appreciated.


Not sure this answers your question, but it might point you towards a solution:

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

(the original site seems to be down so that's a link to the google cache)

The conclusion on that page is that optimistic locking and row level locking are not solutions for race conditions on create, just on update.

The author suggests reimplementing find_or_create with a db constraint.

Another suggestion is that switching the transaction isolation level to 'serializable' ought to work but there's no information on how to do that in Rails.


Just use any locking mechanism like 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜