2011-08-25 16 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 उपयोग किया है, रेल बल्कि एक ही कनेक्शन पहचान के साथ एक नया बनाने पहले से मौजूद पूल लेने के लिए बहुत चालाक है? क्या यह तब भी होता है जब मेरे 5 मॉडल कुछ अमूर्त वर्ग के उप-वर्ग हैं जो establish_connection का उपयोग करते हैं? यदि यह मौजूद है तो क्या यह हमेशा @connection_pools से कनेक्शन लेगा?

अद्यतन 1

मैं एक ठोस उदाहरण के बारे में बात कर रहा हूँ। आपके पास 5 अलग-अलग कनेक्शन वाले 5 मॉडल हैं, प्रत्येक बार रेल एक मॉडल का उपयोग करता है जो इसे establish_connection निष्पादित करता है। ActiveRecord में कोड को देखते हुए, जब यह establish_connection निष्पादित करता है तो यह उस विशिष्ट कनेक्शन से कनेक्शन के साथ एक नया पूल बनाता है। मैं क्या सोच रहा हूं कि क्या हर बार रेल मॉडल के establish_connection पर कॉल करता है, क्या यह एक नया पूल बनाता है या मौजूदा लेता है।

उदाहरण: आप मेरी साइट पर आते हैं और एक उत्पाद सूची देखते हैं। आपने अभी एक ऐसी क्रिया को मारा है जो Product.all पर कॉल करता है, जो अमेज़ॅन पर कुछ डेटाबेस में establish_connection निष्पादित करता है। फिर, मैं उत्पाद सूची में आया, क्या होता है? क्या मैं स्थापित कनेक्शन लेता हूं या क्या मैं उस कनेक्शन के साथ एक नया पूल बना रहा हूं?

अद्यतन 2

मेरा अनुमान है कि पहली बार रेल अपने मॉडल यह अलग कनेक्शन के साथ पूल बनाने है लोड करता है। उसके बाद, जब मैं कुछ Model.method का उपयोग करता हूं, तो यह मॉडल से जुड़े कनेक्शन को पकड़ता है और विधि को निष्पादित करता है।

मुझे यकीन नहीं है कि क्या होता है जब 2 मॉडल के दो बराबर कनेक्शन होते हैं (सार वर्ग में नहीं बल्कि स्वयं वर्ग में)। क्या यह दो समान कनेक्शन पूल उत्पन्न करेगा, या ActiveRecord इस मामले को पकड़ने के लिए पर्याप्त स्मार्ट है?

+3

बीटीडब्ल्यू, बहुत अच्छा सवाल। – bor1s

उत्तर

8

आपको प्रत्येक मॉडल पर establish_connection पर कॉल करने की ज़रूरत नहीं है। आप बस अगले कर सकते हैं:

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

और आपके पास कनेक्शन तक पहुंच होगी। (कोड का यह हिस्सा वास्तविक कोड से निकाला गया है (डेटाबेस नाम को छोड़कर :)))।
लेकिन एपीआई के मुताबिक मुझे लगता है कि रेल दूसरे मॉडल से मौजूदा कनेक्शन नहीं लेता है (अगर मैं गलत हूं तो मुझे सही करें)।
यहां भी link to documentation है। आप वहां कनेक्शन के बारे में और अधिक पढ़ सकते हैं।
मुझे उम्मीद है कि मैंने आपको थोड़ा सा मदद की है।

+0

मेरा संपादित प्रश्न देखें – Filip

+0

रेलों को पहले से स्थापित कनेक्शन – bor1s

+0

माना जाता है, यह मॉडल विधियों को कॉल करते समय पकड़ता है, लेकिन जब यह मॉडल को लोड करता है और establ_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

एआर 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

संबंधित मुद्दे