thiagopradi / octopus

Database Sharding for ActiveRecord
2.53k stars 505 forks source link

Octopus with use_transactional_tests #432

Open mahemoff opened 7 years ago

mahemoff commented 7 years ago

Does Octopus work with Minitest use_transactional_tests (the setting formerly known as use_transactional_fixtures)?

I'm not sure why, but when I integrated Octopus, the tests seem to autocommit during the test (ie I am seeing COMMIT in the logs after each command). I set use_transactional_tests = false and the tests run fine (but slower).

thiagopradi commented 7 years ago

Hi @mahemoff ,

I supposed Octopus should work correctly with use_transactional_tests. Did you end up disabling the transactional tests to use Octopus? Can you provide more information about your configuration/setup?

Thanks,

Thiago

mahemoff commented 7 years ago

I ended up just turning it off for all tests as it wasn't as much of a performance hit (added about 50% test duration).

It's a fairly standard mysql config with Ruby 2.3 and Rails 5 and several shards (though I saw this autocommit situation on a single shard).

satyanash commented 4 years ago

@thiagopradi There is a gist which claims to fix use_transactional_fixtures behavior for octopus: https://gist.github.com/twodollarz/2769765

This gist essentially does the below, when configuring rspec:

config.before do
  shards = ActiveRecord::Base.connection_proxy.instance_variable_get(:@shards)
  @connections = shards.values.map(&:connection)
  @connections.each do |connection|
    connection.increment_open_transactions
    connection.transaction_joinable = false
    connection.begin_db_transaction
  end 
end 

config.after do
  @connections.each do |connection|
    if connection.open_transactions != 0
      connection.rollback_db_transaction
      connection.decrement_open_transactions
    end
  end
end

This blindly runs begin and rollback for all connections registered in octopus. I'm assuming this is needed because rails has no clue that it is supposed to begin/rollback transactions for multiple connections, and will end up choosing only one.

satyanash commented 4 years ago

For rails 5, the updated code looks something like this:

config.before do
  shards = ActiveRecord::Base.connection.instance_variable_get(:@proxy_config).instance_variable_get(:@shards)
  @connections = shards.values.map(&:connection)
  @connections.each do |connection|
    connection.begin_transaction(joinable: false)
  end
end

config.after do
  @connections.each do |connection|
    if connection.open_transactions != 0
      connection.rollback_transaction
    end
  end
end