带有活动记录的Rails控制台中的线程在数据库中找不到模型 [英] Threading in rails console with active record doesn't find Model in the database
问题描述
我正在使用Rails 3和Ruby 1.9.
I'm using Rails 3 and Ruby 1.9.
我正在各种Rails测试中(以及在控制台中)运行2种方法.这些方法称为index_cases
和index_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_numbers
在index_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屋!