如何在使用活动记录和多线程时管理打开和关闭数据库连接 [英] How to manage opening and closing database connections while working with activerecords and multiple threads

查看:19
本文介绍了如何在使用活动记录和多线程时管理打开和关闭数据库连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 rails 中实现一个多线程方法,以便我可以非常快速地创建/更新多个记录.

I am trying to implement a multithreaded method in rails such that I can create/update multiple records very quickly.

这是我的程序大纲.

ActiveRecord::Base.transaction do
  (1..10).each do |i|
    arr[i] = Thread.new {
       <some logic on obj>
       ...
       ...
       obj.save! 
    }
  end
  arr.each {|t| t.join}
end

这在我的日志中给了我警告.

This gives me warnings on my log.

DEPRECATION WARNING: Database connections will not be closed automatically, 
please close your database connection at the end of the thread by calling `close`
on your connection.

它给了我一个错误

could not obtain a database connection within 5 seconds (waited 5.059358 seconds). 
The max pool size is currently 5; consider increasing it.

我试过:- 更改 database.yaml 并增加池大小和超时.- 按以下方式修改现有代码.

I tried: - changing database.yaml and increasing the poolsize and timeout there. - modified the existing code in the following way.

   ActiveRecord::Base.connection_pool.clear_stale_cached_connections!
   begin
     ActiveRecord::Base.transaction do
        (1..10).each do |i|
          arr[i] = Thread.new {
             <some logic on obj>
             ...
             ...
             obj.save!
             ActiveRecord::Base.connection.close 
          }
        end
        arr.each {|t| t.join}
     end
   ensure
     ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
     ActiveRecord::Base.clear_active_connections!
   end

我仍然收到相同的警告和错误.我显然在这里错过了这个概念.我该如何处理?

I am still getting the same warning and error. I am obviously missing the concept here. How do I proceed with this?

推荐答案

为了防止多线程中的连接泄漏,您必须手动管理连接.你可以试试:

To prevent connection leak in multi threads, you have to manage the connection manually. You can try:

Thread.new do
  ActiveRecord::Base.connection_pool.with_connection do
    # Do whatever
  end
end

ActiveRecord::Base.connection_pool.with_connection 的一个问题是它总是准备一个连接,即使里面的代码不需要它.

One problem of ActiveRecord::Base.connection_pool.with_connection is that it always prepare a connection even if the code inside does not need it.

我们可以通过使用ActiveRecord::Base.connection_pool.release_connection来改进它:

We can improve it a little bit by using ActiveRecord::Base.connection_pool.release_connection:

Thread.new do
  begin
    # Do whatever
  ensure
    ActiveRecord::Base.connection_pool.release_connection
  end
end

这篇关于如何在使用活动记录和多线程时管理打开和关闭数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆