ruby-on-rails - 如何在使用 activerecords 和多线程时管理打开和关闭数据库连接

标签 ruby-on-rails multithreading activerecord

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

这是我的程序的概要。

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

这会在我的日志中发出警告。

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并增加池大小和超时。 - 按以下方式修改现有代码。

   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

我仍然收到相同的警告和错误。 我显然在这里缺少这个概念。我该如何继续?

最佳答案

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

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

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

我们可以使用ActiveRecord::Base.connection_pool.release_connection稍微改进一下:

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

关于ruby-on-rails - 如何在使用 activerecords 和多线程时管理打开和关闭数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23596183/

相关文章:

ruby-on-rails - 在 Ruby on Rails 中访问自定义 header 变量

ruby-on-rails - 按日期分组日期并计算行数

ruby-on-rails - 防止为每个评论调用 upvote 模型

c++ - 与锁相比,无论有无争用,原子/互锁变量的速度有多快?

ruby-on-rails - Ruby on Rails 3 - 使用 View 和 Controller 创建插件或引擎?

python - PyQt5 QDialog在后续线程中

c++ - `moveToThread(nullptr)` 是从源线程拉出目标线程内的 QObject 的有效方法吗?

ruby-on-rails - 覆盖 has_many 关联 getter

ruby-on-rails - 使用 where 子句更新查询

mysql - 基于Rails Active Record中两列的组合进行查询