2017-09-19 19 views
1

我們正在考慮涉及兩種模式的預訂系統:StoreReservationStoremax_seatsReservationguests_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.如果在客戶B執行之前客戶A的交易被提交after_create回調,則引發ActiveRecord::Rollback異常並且不創建用於客戶B的記錄。但是,如果after_create回調在客戶A提交事務之前執行,我認爲這會導致超額預訂情況。

A開始交易 - > A進行after_create - >甲提交事務 - > B執行after_create:乙遇到ActiveRecord::Rollback例外

A開始交易 - > A進行after_create - > B執行after_create - >甲提交事務:超售!

如果您可以分享任何見解,我將不勝感激。謝謝。

回答

-1

爲什麼不直接使用before_create呢?你可以這樣做,但爲什麼你會開始寫它到你的數據庫的過程,並提出一個例外,如果你不需要?