ruby-on-rails - Rails 4 多线程和 connection_pool 问题

标签 ruby-on-rails multithreading ruby-on-rails-4 activerecord connection-pooling

我正在尝试对我的 Rails 应用程序进行多线程处理,但在 connection_pool 上遇到了一些问题。我启动了一个线程并执行了一个数据库查询,但似乎从未关闭线程中创建的数据库连接。这是我的代码:

class A
def self.foo
    Thread.new do
      nc1 = ActiveRecord::Base.connection_pool.connections.size
      nw = ""
      nc2 = ""

      ActiveRecord::Base.connection_pool.with_connection do |conns|
        nw = Person.count
        nc2 = ActiveRecord::Base.connection_pool.connections.size
      end

      nc3 = ActiveRecord::Base.connection_pool.connections.size
      puts "First there were #{nc1} connections, after things there were #{nc2} and now finally there are #{nc3} connections, there are #{nw} people in the db"  
    end
  end 
end

当我执行 10.times {A.foo} 它给了我这个输出。
First there were 1 connections, after things there were 3 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 4 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 2 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db
First there were 1 connections, after things there were 5 and now finally there are 5 connections, there are 5325 people in the db

最后我跑了:
ActiveRecord::Base.connection_pool.connections.size
5

现在根据documentation with_connection 应该获取一个 block 并使用一个连接执行它,然后关闭它,但根据我的输出它没有。我真的不明白。

有没有人有任何解决方案或想法为什么会发生这种情况?使用“connection_pool.connections.size”检查有多少连接的正确方法?

有没有其他方法可以在 Rails 中实现多线程数据库查询?

最佳答案

好的,所以我只是不明白 connection_pool 是如何工作的。连接池保存自创建池以来已打开的连接,无论它们是否正在使用。所以我的问题的答案是你不能(以今天的实现方式)connection_pool 来查看哪些连接正在被积极使用。相反,我修补了连接池本身以包含此功能。

如果有人感兴趣,这是我放在 config/initializers/connection_pool_patch.rb 中的补丁:

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPool
      def num_available
        @available.size
      end
    end
  end
end

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPool
      class Queue
        def size
          @queue.size
        end
      end
    end
  end
end

它公开了私有(private)列表@available 的大小,该列表在连接池中保存了可用(即当前未使用但已打开)的连接。用法 = ActiveRecord::Base.connection_pool.num_available

关于ruby-on-rails - Rails 4 多线程和 connection_pool 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30376078/

相关文章:

ruby-on-rails - 如何添加到序列化数组

ruby-on-rails - rails : Use Capybara to browse both local and remote pages in a multi-threaded environment

ruby-on-rails-4 - Rails 4 has_secure_password

ruby-on-rails-3.2 - 在 Rails link_to 中使用 turbolinks

ruby-on-rails - 如何在Rails 4中获取上一页的引荐来源网址

javascript - Rails 渲染 json 显示在屏幕上

mysql - rails : Unknown column in SELECT statement

ruby-on-rails - 阻止 rake db :migrate 的 Drop_table 问题

c - 使用 GDB 单步调试多线程应用程序

c++ - thread_local 的替代方法,用于在 OSX 上调用遗留 C 代码