Jim*_*ngs 5 ruby mysql connection multithreading ruby-on-rails
我在一台MySQL服务器上运行了几个Rails应用程序.它们都运行相同的应用程序,并且所有数据库都具有相同的架构,但每个数据库属于不同的客户.
从概念上讲,这就是我想要做的:
Customer.all.each do |customer|
connection.execute("use #{customer.database}")
customer.do_some_complex_stuff_with_multiple_models
end
Run Code Online (Sandbox Code Playgroud)
此方法不起作用,因为当在Web请求中运行此方法时,基础模型类将缓存来自A/R连接池的不同数据库连接.因此,我执行"use"语句的连接可能不是模型使用的连接,在这种情况下,它查询错误的数据库.
我阅读了Rails A/R代码(版本3.0.3),并提出了在循环中执行的代码,而不是"use"语句:
ActiveRecord::Base.clear_active_connections!
ActiveRecord::Base.establish_connection(each_customer_database_config)
Run Code Online (Sandbox Code Playgroud)
我相信连接池是每个线程的,所以看起来这会破坏连接池并仅为Web请求所在的一个线程重新建立它.但是,如果以某种方式共享连接,我没有看到,我不希望该代码在同一个应用程序中对其他活动Web请求造成严重破坏.
在运行的Web应用程序中这样做是否安全?有没有其他方法可以做到这一点?
现在,ActiveRecord 中的连接可以是每个类级别的。它看起来是基于每个线程的,因为在 1.9 ruby 线程之前,它的实现是使用进程而不是线程,但它可能不会持续很长时间。
但由于 AR 每个模型使用一个线程。您可以为您拥有的每个数据库创建不同的模拟模型。所以使用这个问题中给出的答案。
代码看起来像这样。(我没有测试过)
Customer.all.each do |customer|
c_class = Class.new(ActiveRecord::Base)
c_class.establish_connection(each_customer_database_config)
c_class.table_name = customor.table_name()
c_class.do_something_on_diff_models_using_cutomer_from_diff_conn(customer.id)
c_class.clear_active_connections!
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
595 次 |
| 最近记录: |