I’ve upgraded a Rails app to Rails 7.2 and some of my tests are hanging. We have some cases more or less like this that freeze when the nested transaction starts:
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
Output:
Randomized with seed 1461
starting outer transaction
starting thread
There it freezes forever.
I checked the activity in postgres but it doesn’t help much:
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
I guess this might not be enough to reproduce it but maybe someone can shed some light into why it might happen?
I’m using ruby 3.2 + rails 7.2.2.1 + rspec-rails 7.1.0
Update: the test passes when I switch config.use_transactional_fixtures = true to false in my rspec config, but I’d still like to understand what is causing this issue.
4
It seems like the problem has to do with how I was using uses_transaction(nil)
to prevent specific tests to be wrapped automatically inside of a transaction.
I’ve replaced that implementation like this, and this works:
shared_context 'transactionless' do
self.use_transactional_tests = false
after { DatabaseCleaner.clean_with(:deletion) }
end
Honestly I don’t know what changed but this seems like a better documented way of disabling transactions within a test. (see Transactional Tests: https://api.rubyonrails.org/v7.1/classes/ActiveRecord/FixtureSet.html)
1