2012-08-30 172 views
1

我有模型來存儲數據庫連接參數(主機,數據庫名稱,用戶名,密碼)並填寫它的形式。在創建或更新之前,我需要檢查連接是否適合輸入的參數。我創建validate :check_connection驗證:檢查mysql連接到遠程主機

# don`t change primary connection 
class Remote < ActiveRecord::Base; end 

def check_connection 
    return if errors.any? || (!new_record? && password.empty?) 
    begin 
    Remote.establish_connection(
     adapter: 'mysql2', 
     host: host, 
     username: username, 
     password: password, 
     database: database, 
     connect_timeout: 5, 
     reconnect: false 
    ) 
    # maybe need to make some sql request? did try it 
    rescue Exception => e 
    errors.add :connection, 'Could not connect to database' 
    end 
end 

當我試圖進入訪問主機(localhost),像上面的代碼工作良好。但如果主機像192.168.1.1(無法訪問)頁面凍結後提交表單。我看到每秒連接的嘗試,並且它在瀏覽器(停止加載頁面)後不停止(我在網絡接口上看到tcpdump的嘗試)。並嘗試不停止。

那麼,我該如何驗證連接到數據庫?而如果連接不能建立,頁面必須不會加載很長時間。

+0

我嘗試在軌控制檯'Mysql2 :: Client.new(主持人: '192.168.1.1',數據庫: 'test',用戶名:'user',密碼:'pass',connect_timeout:1,read_timeout:1,write_timeout:1)'並且永久嘗試連接。超時不起作用。哪裏不對? –

回答

0

我確實使用gem 'mysql2'和捆綁安裝0.3.11版本。此版本忽略connect_timeout並修正了較新版本的錯誤。在我嘗試0.3.12b4(gem 'mysql2', '~> 0.3.12b4')之後,一切正常。

+0

phew,一年後,0.3.12還沒有發佈還是:( – Kevin

0

變量connect_timeout是一個全局變量。因此,mysql2可能會忽略它。

上mysql5.6:

mysql[(none)]> set connect_timeout = 123; 
ERROR 1229 (HY000): Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL 

我設置timeout變量初始化mysql2時,但它沒有體現出來。 mysql2自述文件說,你可以設置*超時選項,但我認爲自述文件已過時或損壞。

上mysql2 0.3.14(GEM):

client = Mysql2::Client.new(
    host: 'localhost', 
    database: 'test', 
    username: 'root', 
    password: '', 
    connect_timeout: 3, 
    read_timeout: 3, 
    write_timeout: 3, 
    wait_timeout: 3); 

client.query('show variables like "%timeout%"').map{|r| [r["Variable_name"], r["Value"]] } 

=> [["connect_timeout", "10"], 
["delayed_insert_timeout", "300"], 
["innodb_lock_wait_timeout", "50"], 
["innodb_rollback_on_timeout", "OFF"], 
["interactive_timeout", "28800"], 
["lock_wait_timeout", "31536000"], 
["net_read_timeout", "30"], # Maybe older mysql has read_timeout? 
["net_write_timeout", "60"], # Maybe older mysql has write_timeout? 
["slave_net_timeout", "3600"], 
["wait_timeout", "28800"]] 

如果使用ActiveRecord,您可以通過設置database.ymlwait_timeout變量。

在database.yml中

development: 
    adapter: mysql2 
    encoding: utf8 
    charset: utf8 
    database: test 
    pool: 5 
    username: root 
    password: 
    host: localhost 
    connect_timeout: 3 
    read_timeout: 3 
    write_timeout: 3 
    wait_timeout: 3 

的ActiveRecord 4.0.1的結果:

> ActiveRecord::Base.connection.execute('show variables like "%timeout%"').to_a 
=> [["connect_timeout", "10"], 
["delayed_insert_timeout", "300"], 
["innodb_flush_log_at_timeout", "1"], 
["innodb_lock_wait_timeout", "50"], 
["innodb_rollback_on_timeout", "OFF"], 
["interactive_timeout", "28800"], 
["lock_wait_timeout", "31536000"], 
["net_read_timeout", "30"], 
["net_write_timeout", "60"], 
["rpl_stop_slave_timeout", "31536000"], 
["slave_net_timeout", "3600"], 
["wait_timeout", "3"]] 

ActiveRecord的設置wait_timeout變量abstract_mysql_adapter.rb

看到:

abstract_mysql_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

mysql2_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb