2014-01-24 107 views
0

我寫下面的代碼。目的是爲了避免查詢我的數據庫與活動記錄。ActiveRecord單身危險?

向數據庫發出請求的唯一原因是更新(after_save)。

class Configuration < ActiveRecord::Base 

    def self.instance 
    ConfigurationSingleton.instance.active_record_instance 
    end 

    class ConfigurationSingleton 
    include Singleton 

    def initialize 
     @active_record_instance = Configuration.first || Configuration.new 
    end 

    def active_record_instance 
     @active_record_instance 
    end 
    end 

    after_save Proc.new { ConfigurationSingleton.instance.active_record_instance.reload } 
end 

它似乎在發展模式,但我覺得不安全。 這個代碼安全地運行在apache乘客生產與幾個單獨的過程?

回答

1

如果你有幾個不同的進程運行這個代碼,那麼你最終可能會得到每個進程的「單例」。如果你有多個應用程序服務器,你一定會遇到這個問題。

問題在於將重新加載實例的唯一過程將是保存發生的過程。除非實例保存在這些進程中,否則其他進程都不知道它已經更改。

所以:

  1. 應用服務器1個負載情況下
  2. 應用服務器2點的負載情況下
  3. 實例的應用程序服務器上進行更改1
  4. 應用服務器1個重載實例
  5. 應用服務器2繼續與舊實例
0

通過在列上添加唯一索引並在創建單例時將該列設置爲固定值,您可以輕鬆消除競爭狀況的風險。確保在存在重複時處理SQL異常。

create_table :app_settings do |t| 
    t.integer :unique, null: false, default: 1 
    t.boolean :haz_mojo 
end 
add_index :app_settings, :unique, unique: true 

另一種選擇是,創造了單之後,選擇具有最低ID而不是與創建的參考持續行。