Ruby-on-rails 了解 created_connection 在 ActiveRecord 中的工作原理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7191139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding how establish_connection works in ActiveRecord
提问by Filip
This code was taken from ActiveRecord 2.3.14's gem class ConnectionHandler
此代码取自 ActiveRecord 2.3.14 的 gem 类 ConnectionHandler
def establish_connection(name, spec)
@connection_pools[name] = ConnectionAdapters::ConnectionPool.new(spec)
end
It seems each time ruby calls establish_connectionon the model, it's creating a new connection pool.
似乎每次 ruby 调用establish_connection模型时,它都会创建一个新的连接池。
My question:
我的问题:
If I have 5 models that use establish_connectionto the same database, is Rails smart enough to pick an already existing pool rather creating a new one with the same connection credentials? Does this also happen if my 5 models are subclasses of some abstract class that uses establish_connection? Will it always pick a connection from the @connection_poolsif it exists?
如果我有 5 个模型使用establish_connection同一个数据库,Rails 是否足够聪明来选择一个已经存在的池,而不是创建一个具有相同连接凭据的新池?如果我的 5 个模型是某个使用 的抽象类的子类,这也会发生establish_connection吗?@connection_pools如果它存在,它会总是从 中选择一个连接吗?
Update 1
更新 1
I'm talking about a concrete example. You have 5 models with 5 different connections, each time Rails uses a model it executes establish_connection. Looking at the code in ActiveRecord, when it executes establish_connectionit creates a new pool with connections to that specific connection. What I'm wondering is whether each time Rails calls a model's establish_connection, does it create a new pool or take the existing one.
我说的是一个具体的例子。您有 5 个具有 5 个不同连接的模型,每次 Rails 使用它执行的模型时establish_connection。查看 ActiveRecord 中的代码,当它执行时,establish_connection它会创建一个与该特定连接的连接的新池。我想知道的是,每次 Rails 调用模型的 时establish_connection,它是创建一个新池还是采用现有池。
Example: you come to my site and see a product list. You've just hit an action that calls Product.all, which executes establish_connectionto some database on Amazon. Then, I come to the product list, what happens? Do I grab the established connection or am I creating a new pool with that connection?
示例:您来到我的网站并查看产品列表。您刚刚点击了一个调用 的操作,该操作Product.all将执行establish_connection到 Amazon 上的某个数据库。然后,我来到产品列表,会发生什么?我是获取已建立的连接还是使用该连接创建一个新池?
Update 2
更新 2
My guess is that first time Rails loads my models it's creating pools with different connections. After, when I use some Model.method, it just grabs the connection associated with the model and executes the method.
我的猜测是 Rails 第一次加载我的模型时,它会创建具有不同连接的池。之后,当我使用 some 时Model.method,它只是获取与模型关联的连接并执行该方法。
I'm not sure what happens when 2 models have two equal connections (not in the abstract class but in self class). Will this produce two same connection pools, or is ActiveRecord smart enough to catch this case?
我不确定当 2 个模型有两个相等的连接(不在抽象类中,而是在自类中)时会发生什么。这会产生两个相同的连接池,还是 ActiveRecord 足够聪明来捕捉这种情况?
采纳答案by bor1s
You really do not have to call establish_connectionon each model. You can simply do next:
您真的不必调用establish_connection每个模型。你可以简单地做下一步:
ActiveRecord::Base.establish_connection(
{ :adapter => 'mysql2',
:database => 'some_database',
:host => 'localhost',
:username => 'root',
:password => "" }
)
and you will have access to connection. (This chunk of code has been extracted from real code(except database name :) )).
But according to API I think that Rails does not take existing connection from other model (correct me if I am wrong).
Also here is a link to documentation. You can read more about the connection there.
I hope I helped you alittle.
您将可以访问连接。(这段代码是从真实代码中提取的(数据库名称除外:)))。
但是根据 API,我认为 Rails 不会从其他模型获取现有连接(如果我错了,请纠正我)。
这里还有一个指向文档的链接。您可以在那里阅读有关连接的更多信息。
我希望我对你有所帮助。
回答by Mark Devo Lanett
AR calls establish_connection only once, for ActiveRecord::Base. All subclasses use the one connection.
对于 ActiveRecord::Base,AR 只调用了一次 created_connection。所有子类都使用一个连接。
You can manually call establish connection yourself on some subclasses. This is very convenient for using two databases at once, e.g.
您可以在某些子类上手动调用建立连接。这对于同时使用两个数据库非常方便,例如
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
You can't do queries that would cross databases though.
但是,您不能执行跨数据库的查询。
回答by halogenandtoast
This comment:
这条评论:
# 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
Should explain the situation
应该说明情况

