带有活动记录的Rails控制台中的线程在数据库中找不到模型 [英] Threading in rails console with active record doesn't find Model in the database

查看:59
本文介绍了带有活动记录的Rails控制台中的线程在数据库中找不到模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Rails 3和Ruby 1.9.

I'm using Rails 3 and Ruby 1.9.

我正在各种Rails测试中(以及在控制台中)运行2种方法.这些方法称为index_casesindex_new_cases,方法主体如下所示. index_new_cases方法的内容可能无关紧要(我正在使用Sunspot gem为ModelCase信息编制索引),但为了完整起见,我将其保留在那里.

I'm running 2 methods in various rails tests (and in the console). The methods are called index_cases and index_new_cases and the method bodies are shown below. The contents of the index_new_cases method probably aren't relevant (I'm indexing ModelCase information using the Sunspot gem), but I leave it there for completeness.

我有3个case_numbers.每个case_number都与数据库中的ModelCase匹配(即,数据库中有3个ModelCase记录).

I have 3 case_numbers. Each case_number matches a ModelCase in the database (i.e. there are 3 ModelCase records in the db).

当我使用这3个case_numbersindex_cases方法上运行测试时,index_new_cases方法不会使用ModelCase.where…方法检索任何案例.但是,如果我删除了index_cases方法中的线程"调用,则index_new_cases函数现在将检索所有3种情况并正确地为它们建立索引.

When I use those 3 case_numbers to run tests on the index_cases method, the index_new_cases method does NOT retrieve any cases using the ModelCase.where… method. However, if i remove the "threading" calls in the index_cases method, the index_new_cases function now retrieves all 3 cases and indexes them properly.

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

Can anyone explain to me why my threads can't find the database records? Is my threading implementation wrong? Thanks!

  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


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


This method (without threading) works properly to find and index my database records

  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

推荐答案

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

I had a very similar problem, though only in tests.

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

The problem lies in the transactions that are used in test cases (when transactional fixtures are on) - changes to data are not visible to other connections as long as the transaction is not committed.

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

因此,在您的外部看不到数据库更改 连接,直到操作完成.

As a consequence changes to the database are not seen outside your connection until the operation is complete.

线程应与数据库建立新连接.而且由于使用事务性固定装置时,整个测试运行都封装在一个事务中,因此线程内部看不到任何东西,除非它们是自己创建的.

Threads should have a new connection to the database. And since when using transactional fixtures, the whole test run is wrapped in a transaction, nothing inside it will be visible to threads, except what they create on their own.

幸运的是,您也可以关闭交易以进行单个测试: http://ar.rubyonrails .org/classes/Fixtures.html

You can turn off the transactions, luckily also for single tests: http://ar.rubyonrails.org/classes/Fixtures.html

这篇关于带有活动记录的Rails控制台中的线程在数据库中找不到模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆