带有活动记录的 rails 控制台中的线程在数据库中找不到模型

use*_*146 5 ruby multithreading ruby-on-rails thread-safety

我正在使用 Rails 3 和 Ruby 1.9。

我在各种 Rails 测试(和控制台)中运行 2 种方法。方法被调用index_casesindex_new_cases方法体如下所示。该index_new_cases方法的内容可能不相关(我正在使用 Sunspot gem 索引 ModelCase 信息),但为了完整性我将其保留在那里。

我有 3 case_numbers。每个case_number匹配ModelCase数据库中的一个(即数据库中有 3ModelCase条记录)。

当我使用这 3 个case_numbersindex_cases方法运行测试时,该index_new_cases方法不会使用该ModelCase.where…方法检索任何案例。但是,如果我删除方法中的“线程”调用index_cases,该index_new_cases函数现在会检索所有 3 个案例并正确索引它们。

谁能向我解释为什么我的线程找不到数据库记录?我的线程实现是错误的吗?谢谢!

  def index_cases(case_numbers)
    threads = []
    case_numbers.each_slice(500) do |slice_of_case_numbers|
      threads << Thread.new(slice_of_case_numbers) do |a_slice|
        index_new_cases(a_slice)
      end
    end
    threads.each {|thr| thr.join}
  end

  def index_new_cases(case_numbers)
    cs = ModelCase.where(case_number: case_numbers).includes(:child_tables)
    puts cs.size # prints 0 with threading and 3 without threading
    Sunspot.index(cs)
    Sunspot.commit
  end
Run Code Online (Sandbox Code Playgroud)

此方法(无线程)可以正常工作以查找和索引我的数据库记录

  def index_cases(case_numbers)
    #threads = []
    case_numbers.each_slice(500) do |slice_of_case_numbers|
      #threads << Thread.new(slice_of_case_numbers) do |a_slice|
        index_new_cases(slice_of_case_numbers)
     #end
    end
    #threads.each {|thr| thr.join}
  end
Run Code Online (Sandbox Code Playgroud)

Mar*_* T. 5

我有一个非常相似的问题,尽管只是在测试中。

问题在于测试用例中使用的事务(当事务固定装置打开时) - 只要事务未提交,其他连接就看不到数据的更改。

请参阅http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

因此,在操作完成之前,在您的连接之外不会看到对数据库的更改。

线程应该有一个到数据库的新连接。并且由于在使用事务性fixtures时,整个测试运行都包含在一个事务中,除了它们自己创建的内容之外,线程中的任何内容都不会被线程看到。

您可以关闭事务,幸运的是也可以用于单个测试:http : //ar.rubyonrails.org/classes/Fixtures.html