的ActiveRecord :: ConnectionTimeoutError

0xS*_*ina 8 ruby activerecord

我收到此错误:

'could not obtain a database connection within 5 seconds (waited 5.001017 seconds). The max pool size is currently 16; consider increasing it.'
Run Code Online (Sandbox Code Playgroud)

首先我得到了这个错误,我将计数从5提升到16.但它仍然在发生,我是唯一一个测试数据库的人.当我是唯一的用户时,为什么会这样?

我不在轨道上.我在用:

ActiveRecord::Base.establish_connection ({
    :adapter => 'mysql2',
    :database => 'ck',
    :host => 'localhost',
    :username => 'root',
    :password => '',
    :pool => 16,
    })
Run Code Online (Sandbox Code Playgroud)

并使用Sinatra.

谢谢

kuw*_*rty 12

正如Frederick所指出的,您需要将打开的ActiveRecord连接返回到连接池.

如果您在线程模式下使用Thin服务器,则需要将其添加到Sinatra应用程序:

after do
  ActiveRecord::Base.connection.close
end
Run Code Online (Sandbox Code Playgroud)

...而不是使用ConnectionManagement建议.原因是Thin将请求处理分为2个线程,而关闭ActiveRecord连接的线程与打开它的线程不同.由于ActiveRecord按线程ID跟踪连接,因此会混淆并且不会正确返回连接.

  • 是否有理由使用`ActiveRecord :: Base.connection.close`而不是'ActiveRecord :: Base.clear_conne_connections!`,如[docs]中所述(http://api.rubyonrails.org/classes/ActiveRecord/ ConnectionAdapters/ConnectionPool.html)?这简直过时了吗? (3认同)
  • 在哪里使用? (2认同)

Fre*_*ung 5

听起来您在请求结束时没有返回到池的连接.如果没有,则每个使用db的请求将消耗1个连接,最终您将耗尽池并开始获取您描述的错误消息

Active Record提供了一个机架中间件来处理这个问题ActiveRecord::ConnectionAdapters::ConnectionManagement,它应该像中间件链中的早期一样处理事情,而不是任何访问活动记录的东西.

您也可以自己处理连接管理.该文档有更多的细节,但这样做是坚持所有的分贝的一种方式在这样的块访问

ActiveRecord::Base.connection_pool.with_connection do
  ...
end
Run Code Online (Sandbox Code Playgroud)

在块开始时检查连接并在之后检查它.