DatabaseCleaner / database_cleaner-active_record

Strategies for cleaning databases using ActiveRecord. Can be used to ensure a clean state for testing.
MIT License
64 stars 63 forks source link

Transactions are flakey in rails 5/6 when there are multiple connections or using shards #47

Closed ryanong closed 4 months ago

ryanong commented 4 years ago

Most of this code is copied from the rails transaction management for fixtures

I am unsure how to proceed here. Testing is a lot and not sure I love how it does version detection.

This is to address #24

ryanong commented 4 years ago

I explained it a bit in the linked issue but I'll gladly explain it again.

Connection Pool can have many connections, each connection can have it's own transaction. It can also share transaction but that has to be explicit.

The current strategy of database_cleaner only opens one transaction and that is for the current active connection of the current connection_class. If there is any threaded code that perhaps opens a new connection or any code that explicitly creates a new connection, those new connections won't share the transaction of the connection_class that was created. The rails code that I copied over ensures that all new connections that are created in the connection pool share the transaction of the first.

This bug can show up as missing data because the data was created in the initial connection transaction but the new connection is outside of that transaction.

As for file locations for rails 5 https://github.com/rails/rails/blob/5-0-stable/activerecord/lib/active_record/fixtures.rb#L973 for rails 6 https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/test_fixtures.rb#L114

Rails 6.1 does it a bit differently also, so may have to create a separate driver for that