【发布时间】:2017-03-02 00:08:59
【问题描述】:
在这篇博文之后,http://blog.arkency.com/2015/09/testing-race-conditions/
我正在尝试测试并发性。但在我的规范中,当我启动一个新线程或分叉一个进程时,我无法找到记录。
describe 'test concurrency' do
let(:order_1) { create(:order) }
let(:order_2) { create(:order) }
let(:order_3) { create(:order) }
let(:order_4) { create(:order) }
let(:product) { create(:product) }
it 'test concurrency' do
wait_for_all_threads = true
product.update(quantity_available: 4, quantity_sold: 0, quantity_in_carts: 0)
orders = [order_1, order_2, order_3, order_4]
# Objects are persisted in here
# because order_n.persisted => true
# product.persisted => true
# product.reload works without issue (and this is essentially what causes the RecordNotFound error in Order#add_item)
threads = orders.map do |order|
Thread.new do
# Objects cannot be found in the database
true while wait_for_all_threads
item = order.add_item(product, 1)
order_items << item
end
end
wait_for_all_threads = false
threads.each(&:join)
# ...
# here comes all the expects ...
# not gonna post it because it's not what matters in this question
end
end
经过研究,我设置了这些:
DatabaseCleaner.strategy = :truncation
config.use_transactional_fixtures = false
但没有运气。
所以问题是,在新线程中,在数据库中找不到任何创建的对象。
我正在挖掘的一些线索:
- 当我通过 sql 客户端直接连接时,数据库一直是空的。 (当我在测试中添加断点,并验证对象是
persisted?) - factory girl / rspec 是否真的将数据提交到数据库?如果没有,那么新线程将无法读取它,因为它仍在 bin 日志或内存中? (这提示我,因为我记得
after_commit不会在 rspec 中运行)
【问题讨论】:
-
嗨...这不是您的所有代码...而且绝对不是与此问题相关的所有代码。您能否向我们展示您实际设置数据库中对象的代码?还有 - 显示您如何测试对象是否在数据库中的代码?
-
@TarynEast 当然,请查看我的编辑。
标签: ruby-on-rails ruby multithreading rspec factory-bot