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

我试图在rails中实现multithreading方法,以便我可以非常快速地创建/更新多个记录。

这是我的计划的大纲。

ActiveRecord::Base.transaction do (1..10).each do |i| arr[i] = Thread.new {  ... ... 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并增加poolize和timeout。 – 以下列方式修改现有代码。

  ActiveRecord::Base.connection_pool.clear_stale_cached_connections! begin ActiveRecord::Base.transaction do (1..10).each do |i| arr[i] = Thread.new {  ... ... 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 

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

要防止multithreading中的连接泄漏,您必须手动管理连接。 你可以试试:

 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 

如果要在N个线程中运行,请确保池中有N个连接

 # ActiveRecord::Base.connection_config # # => {pool: 5, timeout: 5000, database: "db/development.sqlite3", adapter: "sqlite3"} 

否则你将能够从池中获取连接。