diff --git a/lib/database_cleaner/active_record/transaction.rb b/lib/database_cleaner/active_record/transaction.rb index ad49cf7..540011a 100644 --- a/lib/database_cleaner/active_record/transaction.rb +++ b/lib/database_cleaner/active_record/transaction.rb @@ -27,24 +27,26 @@ module DatabaseCleaner::ActiveRecord def clean - return unless connection_class.connection.open_transactions > 0 + connection_class.connection_pool.connections.each do |connection| + next unless connection.open_transactions > 0 - if connection_class.connection.respond_to?(:rollback_transaction) - connection_class.connection.rollback_transaction - else - connection_class.connection.rollback_db_transaction - end - - # The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99 - if connection_class.connection.respond_to?(:rollback_transaction_records, true) - connection_class.connection.send(:rollback_transaction_records, true) - end - - if connection_maintains_transaction_count? - if connection_class.connection.respond_to?(:decrement_open_transactions) - connection_class.connection.decrement_open_transactions + if connection.respond_to?(:rollback_transaction) + connection.rollback_transaction else - connection_class.__send__(:decrement_open_transactions) + connection.rollback_db_transaction + end + + # The below is for handling after_commit hooks.. see https://github.com/bmabey/database_cleaner/issues/99 + if connection.respond_to?(:rollback_transaction_records, true) + connection.send(:rollback_transaction_records, true) + end + + if connection_maintains_transaction_count? + if connection.respond_to?(:decrement_open_transactions) + connection.decrement_open_transactions + else + connection_class.__send__(:decrement_open_transactions) + end end end end diff --git a/spec/database_cleaner/active_record/transaction_spec.rb b/spec/database_cleaner/active_record/transaction_spec.rb index a1bf915..8e3515d 100644 --- a/spec/database_cleaner/active_record/transaction_spec.rb +++ b/spec/database_cleaner/active_record/transaction_spec.rb @@ -7,7 +7,11 @@ module DatabaseCleaner describe Transaction do let (:connection) { double("connection") } + let (:connection_2) { double("connection") } + let (:connection_pool) { double("connection_pool")} before(:each) do + ::ActiveRecord::Base.stub(:connection_pool).and_return(connection_pool) + connection_pool.stub(:connections).and_return([connection]) ::ActiveRecord::Base.stub(:connection).and_return(connection) end @@ -82,6 +86,40 @@ module DatabaseCleaner ::ActiveRecord::Base.should_receive(:decrement_open_transactions) Transaction.new.clean end + + it "should rollback open transactions in all connections" do + connection_pool.stub(:connections).and_return([connection, connection_2]) + + connection.should_receive(:open_transactions).and_return(1) + connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(false) + connection.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false) + connection.stub(:respond_to?).with(:rollback_transaction).and_return(false) + connection.stub(:rollback_db_transaction) + + connection_2.should_receive(:open_transactions).and_return(1) + connection_2.stub(:respond_to?).with(:decrement_open_transactions).and_return(false) + connection_2.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false) + connection_2.stub(:respond_to?).with(:rollback_transaction).and_return(false) + connection_2.stub(:rollback_db_transaction) + + ::ActiveRecord::Base.should_receive(:decrement_open_transactions).twice + Transaction.new.clean + end + + it "should rollback open transactions in all connections with an open transaction" do + connection_pool.stub(:connections).and_return([connection, connection_2]) + + connection.should_receive(:open_transactions).and_return(1) + connection.stub(:respond_to?).with(:decrement_open_transactions).and_return(false) + connection.stub(:respond_to?).with(:rollback_transaction_records, true).and_return(false) + connection.stub(:respond_to?).with(:rollback_transaction).and_return(false) + connection.stub(:rollback_db_transaction) + + connection_2.should_receive(:open_transactions).and_return(0) + + ::ActiveRecord::Base.should_receive(:decrement_open_transactions).exactly(1).times + Transaction.new.clean + end end context "automatic accounting of transaction count (AR 4)" do