diff --git a/lib/mini_sql_multisite_connection.rb b/lib/mini_sql_multisite_connection.rb index a1cd6a6897e..202cf87b4e1 100644 --- a/lib/mini_sql_multisite_connection.rb +++ b/lib/mini_sql_multisite_connection.rb @@ -43,8 +43,16 @@ class MiniSqlMultisiteConnection < MiniSql::Postgres::Connection end # Allows running arbitrary code after the current transaction has been committed. - # Works even with nested transactions. Useful for scheduling sidekiq jobs. + # Works with nested ActiveRecord transaction blocks. Useful for scheduling sidekiq jobs. + # If not currently in a transaction, will execute immediately def after_commit(&blk) + return blk.call if !ActiveRecord::Base.connection.transaction_open? + + # In tests, everything is run inside a transaction. + # To run immediately, check for joinable? transaction + # This mimics core rails behavior: https://github.com/rails/rails/blob/348e142b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L211 + return blk.call if Rails.env.test? && !ActiveRecord::Base.connection.current_transaction.joinable? + ActiveRecord::Base.connection.add_transaction_record( AfterCommitWrapper.new(&blk) ) diff --git a/spec/lib/mini_sql_multisite_connection_spec.rb b/spec/lib/mini_sql_multisite_connection_spec.rb index 4d404a4c926..9cfa452178d 100644 --- a/spec/lib/mini_sql_multisite_connection_spec.rb +++ b/spec/lib/mini_sql_multisite_connection_spec.rb @@ -49,6 +49,19 @@ describe MiniSqlMultisiteConnection do expect(outputString).to eq("123") end + + it "runs immediately if there is no transaction" do + outputString = "1" + + DB.after_commit do + outputString += "2" + end + + outputString += "3" + + expect(outputString).to eq("123") + end + end end