我有一个非常简单的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])
感觉有更好的方法可以做到这一点,但我无法完全理解它是什么。任何有关如何防止竞争状况的帮助将不胜感激。
答案 0 :(得分:0)
不确定这会回答您的问题,但它可能会指向您找到解决方案:
(原始网站似乎已关闭,因此这是指向Google缓存的链接)
该页面上的结论是乐观锁定和行级别锁定不是创建时竞争条件的解决方案,只是在更新时。
作者建议使用db约束重新实现find_or_create。
另一个建议是将事务隔离级别切换为“可序列化”应该可以工作,但是没有关于如何在Rails中执行此操作的信息。
答案 1 :(得分:0)
只需使用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