我们正在考虑预订系统,其中涉及两个模型:Store
和Reservation
。 Store
有max_seats
,Reservation
有guests_count
列。
为避免超量预订,我们已实施验证。如果超量预订,则回滚事务。但我不确定这是否足以抵御竞争条件。
像这样:
class Store < ActiveRecord::Base
has_many :reservations
validates :max_seats, presence: true, numericality: true
end
class Reservation < ActiveRecord::Base
belongs_to :store
validates :guests_count, presence: true, numericality: true
after_create do
total_seats_taken = reservation_slot.reservations.sum(&:guests_count)
unless total_seats_taken <= store.max_seats
raise ActiveRecord::Rollback
end
end
end
我怀疑这种scnenerio仍然可能发生,即使它很少见:
假设客户A和客户B分别在同一时间单独预订6个席位,max_seats
设置为10.如果客户A的交易在客户B执行之前提交{{ 1}}回调,after_create
异常被引发,并且未创建客户B的记录,这是预期的。但是,如果在提交客户A的交易之前执行ActiveRecord::Rollback
回调,我认为这将导致超额预订。
A开始交易 - &gt; A执行after_create
- &gt;提交交易 - &gt; B执行after_create
:B遇到after_create
例外
A开始交易 - &gt; A执行ActiveRecord::Rollback
- &gt; B执行after_create
- &gt;提交交易:超量预订!!
如果你能分享任何见解,我将不胜感激。谢谢。
答案 0 :(得分:-1)
为什么不直接使用before_create?你可以按照自己的方式去做,但是为什么你会想要开始将它写入数据库并在不需要时引发异常?