【问题标题】:ActiveRecord::ConnectionTimeoutErrorActiveRecord::ConnectionTimeoutError
【发布时间】:2012-12-03 01:19:51
【问题描述】:

我收到此错误:

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

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

顺便说一句,我不在轨道上。我正在使用:

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

并使用 Sinatra。

谢谢

【问题讨论】:

    标签: ruby activerecord


    【解决方案1】:

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

    如果您在线程模式下使用瘦服务器,那么您需要将其添加到您的 Sinatra 应用程序中:

    after do
      ActiveRecord::Base.connection.close
    end
    

    ...而不是使用 ConnectionManagement 建议。原因是 Thin 将请求处理拆分为 2 个线程,并且关闭 ActiveRecord 连接的线程与打开它的线程不同。由于 ActiveRecord 通过线程 ID 跟踪连接,它会感到困惑并且无法正确返回连接。

    【讨论】:

    • @squixy - 把它放在你的应用中任何扩展的类中 Sinatra::Base
    • 您使用ActiveRecord::Base.connection.close 而非docs 中指定的ActiveRecord::Base.clear_active_connections! 是否有原因?这只是过时了吗?
    【解决方案2】:

    听起来您没有在请求结束时将连接返回到池。如果不是,那么使用 db 的每个请求都将消耗 1 个连接,最终您将耗尽池并开始收到您描述的错误消息

    Active Record 提供了一个机架中间件来处理这个ActiveRecord::ConnectionAdapters::ConnectionManagement,只要它在中间件链中比任何访问活动记录的东西更早,它就应该处理所有事情。

    您也可以自己处理连接管理。 docs 有更多详细信息,但其中一种方法是将所有的数据库访问都粘贴在这样的块中

    ActiveRecord::Base.connection_pool.with_connection do
      ...
    end
    

    它会在块的开头签出一个连接,然后再将其签入。

    【讨论】:

    • 谢谢。我应该在 ActiveRecord::Base.establish_connection 之前调用它吗?
    • 这是我在脚本中调用的第一件事,但仍然收到相同的错误:(
    • “调用它”是什么意思?您是否将其添加到中间件堆栈中? (Sinatra 文档有示例 iirc)
    【解决方案3】:

    最好使用 ActiveRecord 提供的middleware

    use ActiveRecord::ConnectionAdapters::ConnectionManagement
    

    【讨论】:

      【解决方案4】:

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

      正如 kuwerty 建议的那样,当您使用 Thin 时,ConnectionManagement 不会返回连接池。我建议不要像 kuwerty 说的那样关闭当前连接,而是像这样将连接返回到池中。

      after do
        ActiveRecord::Base.clear_active_connections!
      end
      

      对于那些想要重现问题的人,请尝试this example

      编辑:

      我解释了为什么在线程模式下使用中间件 ActiveRecord::Connectionadapters::ConnectionManagement 无法与 Thin 一起工作,您可以找到 here

      【讨论】:

        猜你喜欢
        • 2017-04-14
        • 2016-12-26
        • 1970-01-01
        • 2014-05-31
        • 2013-09-24
        • 1970-01-01
        • 2021-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多