如何在使用ActiveRecord和多个线程时管理打开和关闭数据库连接 [英] How to manage opening and closing database connections while working with activerecords and multiple threads
问题描述
我正在尝试在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
这篇关于如何在使用ActiveRecord和多个线程时管理打开和关闭数据库连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!