我已将 Rails 应用程序升级到 Rails 7.2,但我的一些测试挂起。我们有一些或多或少像这样的情况,当嵌套事务开始时会冻结:
context 'error', :transactionless do
let(:concurrent) do
Thread.new do
FlowLead.transaction do
puts 'inside of the transaction'
end
end
end
it 'should not hang' do
puts 'starting outer transaction'
FlowLead.transaction do
puts 'starting thread'
concurrent.join
puts 'after inner transaction'
end
end
end
shared_context 'transactionless' do
uses_transaction(nil)
after { DatabaseCleaner.clean_with(:deletion) }
end
输出:
Randomized with seed 1461
starting outer transaction
starting thread
它永远冻结了。
我检查了 postgres 中的活动,但没有多大帮助:
SELECT * FROM pg_stat_activity;
292084 testdb 78482 NULL 10 postgres /Users/me/.rbenv/versions/3.2.2/bin/rspec 127.0.0.1 NULL 61253 2024-12-16 18:51:36.963283+01 2024-12-16 18:51:37.174001+01 2024-12-16 18:51:37.272498+01 2024-12-16 18:51:37.272507+01 Client ClientRead idle in transaction 510729 NULL NULL RELEASE SAVEPOINT active_record_1 client backend
我想这可能不足以重现它,但也许有人可以解释为什么会发生这种情况?
我正在使用 ruby 3.2 + Rails 7.2.2.1 + rspec-rails 7.1.0
更新:当我在 rspec 配置中将 config.use_transactional_fixtures = true 切换为 false 时,测试通过,但我仍然想了解导致此问题的原因。
问题似乎与我如何使用
uses_transaction(nil)
来防止特定测试自动包装在事务中有关。
我已经像这样替换了该实现,并且这有效:
shared_context 'transactionless' do
self.use_transactional_tests = false
after { DatabaseCleaner.clean_with(:deletion) }
end
老实说,我不知道发生了什么变化,但这似乎是在测试中禁用事务的更好记录的方法。 (请参阅事务测试:https://api.rubyonrails.org/v7.1/classes/ActiveRecord/FixtureSet.html)