2011-08-25 24 views
31

establish_connection作品這段代碼是從ActiveRecord的2.3.14的寶石類ConnectionHandler瞭解如何在ActiveRecord的

def establish_connection(name, spec) 
    @connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec) 
end 

採取好像每次紅寶石的模式要求establish_connection,它創建一個新的連接池。

我的問題:

如果我有5款車型使用establish_connection到同一個數據庫,是Rails的足夠聰明,選擇一個已經存在的池,而創建一個新的具有相同的連接憑據?如果我的5個模型是使用establish_connection的抽象類的子類,這是否也會發生?如果它存在,它是否總是會從@connection_pools中選擇一個連接?

更新1

我說的是一個具體的例子。你有5個不同連接的模型,每次Rails使用它執行的模型establish_connection。查看ActiveRecord中的代碼,當它執行establish_connection時,它會創建一個連接到該特定連接的新池。我想知道的是每次Rails調用模型的establish_connection時,它是否會創建一個新的池或採用現有的池。

例如:您來到我的網站並查看產品列表。您剛剛執行了一項操作,稱爲Product.all,該操作會在亞馬遜的某個數據庫上執行establish_connection。然後,我來到產品清單,會發生什麼?我是否抓住已建立的連接,或者是否創建了具有該連接的新池?

更新2

我的猜測是,第一次的Rails加載我的模型它創建具有不同的連接池。之後,當我使用一些Model.method時,它只抓取與模型相關的連接並執行該方法。

我不確定當2個模型有兩個相等的連接(不在抽象類中,但在自我類中)會發生什麼。這會產生兩個相同的連接池,還是ActiveRecord足夠聰明,可以捕捉到這種情況?

+3

順便說一句,很好的問題。 – bor1s

回答

8

你真的不必調用establish_connection每個模型。您可以簡單地做下一步:

ActiveRecord::Base.establish_connection(
{ :adapter => 'mysql2', 
    :database => 'some_database', 
    :host => 'localhost', 
    :username => 'root', 
    :password => "" } 
) 

並且您將有權訪問連接。 (這段代碼已經從實際代碼中提取出來(數據庫名稱除外:)))。
但根據API我認爲,Rails不會從其他模型的現有連接(糾正我,如果我錯了)。
此處還有一個link to documentation。你可以閱讀更多關於那裏的連接。
我希望我幫助你。

+0

看到我編輯的問題 – Filip

+0

似乎是已建立的Rails抓取連接 – bor1s

+0

它調用模型方法時抓取,但在初始化狀態時它只是加載模型並執行establish_connection,查看代碼只是創建一個池,無論如果它已經存在。 @connection_pool散列中的鍵不同,但值相同。 – Filip

2

此評論:

# Check-out a database connection from the pool, indicating that you want 
# to use it. You should call #checkin when you no longer need this. 
# 
# This is done by either returning an existing connection, or by creating 
# a new connection. If the maximum number of connections for this pool has 
# already been reached, but the pool is empty (i.e. they're all being used), 
# then this method will wait until a thread has checked in a connection. 
# The wait time is bounded however: if no connection can be checked out 
# within the timeout specified for this pool, then a ConnectionTimeoutError 
# exception will be raised. 

來自:https://github.com/rails/rails/blob/dd944cbf5879e675fff541d1be7c7eb6c3382d01/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb#L242-251

應說明情況

14

AR調用establish_connection只有一次,ActiveRecord的::基地。所有的子類都使用一個連接。

您可以在某些子類上手動調用建立連接。這對於一次使用兩個數據庫非常方便,例如,

class MyMainUser < ActiveRecord::Base; end 
class MyOtherDb < ActiveRecord::Base; end 
class MyOtherUser < MyOtherDb; end 

MyOtherDb.establish_connection ... 

MyMainUser.first # uses default db 
MyOtherUser.first # uses other db 

你不能做跨越數據庫的查詢。

+0

我不得不在myOtherDb類中添加'self.abstract_class = true'來運行插入。否則,它試圖讓'my_other_dbs'表不存在。 – iamprem