Ruby on rails Rails 4多线程应用程序-ActiveRecord::ConnectionTimeoutError

Ruby on rails Rails 4多线程应用程序-ActiveRecord::ConnectionTimeoutError,ruby-on-rails,database,multithreading,activerecord,Ruby On Rails,Database,Multithreading,Activerecord,我有一个简单的rails应用程序,它为模型的每个实例从远程URL中提取JSON(我们称之为JSON)。然后,应用程序在第一个应用程序的关联模型下创建一个新数据点。让我们称之为中间模型B和数据点模型C。还有一个前端,让用户以图形/视觉方式浏览这些数据 因此,层次结构是A有许多->B有许多->C。我为每个A刮取一个URL,它返回几个B的实例,其中包含相应B的数据的新C 在尝试测试/扩展此应用程序时,我遇到了一个问题,rails将停止处理,挂起一段时间,最后抛出一个“ActiveRecord::Con

我有一个简单的rails应用程序,它为模型的每个实例从远程URL中提取JSON(我们称之为JSON)。然后,应用程序在第一个应用程序的关联模型下创建一个新数据点。让我们称之为中间模型B和数据点模型C。还有一个前端,让用户以图形/视觉方式浏览这些数据

因此,层次结构是A有许多->B有许多->C。我为每个A刮取一个URL,它返回几个B的实例,其中包含相应B的数据的新C

在尝试测试/扩展此应用程序时,我遇到了一个问题,rails将停止处理,挂起一段时间,最后抛出一个“ActiveRecord::ConnectionTimeoutError无法在5.000秒内获得数据库连接”,显然5只是默认值

我不明白为什么在1)没有显式进行DB调用时会发生这种情况,2)日志中没有显示任何在正常工作时发生的引擎盖下DB调用3)有时有效,有时无效

rails 4 AR和连接池怎么了

几点注意:

  • 一般的算法是为每个模型a生成一个线程,刮取数据,在内存中创建模型C的新实例,最后在一个事务中保存所有C
  • 有时候这样行得通,有时候不行,我不知道是什么原因导致它失败。然而,一旦失败,它似乎失败越来越多
  • 我急切地开始加载所有的A型和B型
  • 我在最后使用一个事务插入所有新创建的C实例
  • 我目前使用resque和resque scheduler来完成这项工作,但我高度怀疑它们是问题的根源,因为即使我只是执行“rails runner Class.do_work”,问题仍然存在
  • 非常感谢您的任何建议和想法

    如果您正在使用

    ActiveRecord::Base.transaction do 
    
        ... code
    
    end
    

    要在线程中完成更快的事务,请注意,这会锁定数据库。我有一个应用程序,它在一个线程中为一个非常昂贵的进程实现了这一点,它将锁定数据库超过5秒。速度更快,但会锁定您的数据库

    我相信我已经找到了这个问题的原因。当您通过

    model.association.each do |a|
       #work here
    end
    
    Rails做一些“使用”DB连接的幕后工作。我用引号括起来,因为在我的例子中,我认为结果实际上是从内存返回的。我急切地加载了关联,因此数据库从未真正被命中

    将我的区块包装在一个容器中的初步测试

    ActiveRecord::Base.connection_pool.with_connection do 
    #something me doing?
    end
    
    似乎已经解决了这个问题

    我通过在打印出来的线程错误消息中添加回溯来发现这一点

    -----对于使用resque的用户----

    我还必须在resque.rake文件中添加一点,以使其完全按照预期工作

    task 'resque:setup' => :environment do 
      Resque.after_fork do |job|
        ActiveRecord::Base.establish_connection
      end
    end
    

    对于迟来的回复表示歉意,并感谢您的努力。但是,我并没有在每个线程中执行事务。事情的流程是加载所有关联,生成线程以收集数据,然后在所有线程完成后,在一个事务中将所有新信息保存到DB。不过,您可能了解到了一些事情,DB保持锁定的时间比我最初预期的要长。