Active Record 和涉及多个数据库的多线程

Sam*_*ron 5 activerecord ruby-on-rails

我有一个多宿主 Rails 应用程序。

foo.mysite.com与“foo”数据库对话。

bar.mysite.com与“bar”数据库对话。

这是通过调用以下方法来完成的:

ActiveRecord::Base.connection_handler.establish_connection("ActiveRecord::Base", foo_spec)

当请求 foo 时,它使用 foo_spec,当请求传入 bar 时,它使用 bar_spec。

一切皆大欢喜,世界太平。

然而,

我也使用它sidekiq,它是多线程的。

我在 sidekiq 中遇到奇怪的行为。通常当我以为我正在与 foo_db 交谈时,ActiveRecord::Base.connection就会被指向 bar_db。

我深入研究代码并发现:

 def retrieve_connection_pool(klass)
    pool = @class_to_pool[klass.name]
    return pool if pool
    return nil if ActiveRecord::Base == klass
    retrieve_connection_pool klass.superclass
  end
Run Code Online (Sandbox Code Playgroud)

事实证明,AR 的内部设计只允许 AR::Base 了解单个连接池。

有没有办法让线程 1 与 db1 对话,线程 2 同时与 db2 对话,使用ActiveRecord::Base.connection

Jam*_*els -1

我建议使用 Postgres 和单独的模式,而不是完全单独的数据库;那就是你可以共享池。

用法如下:select * from foo.users,select * from bar.users

您可以将架构作为参数传递给后台工作人员。