File tree Expand file tree Collapse file tree 2 files changed +26
-5
lines changed
Expand file tree Collapse file tree 2 files changed +26
-5
lines changed Original file line number Diff line number Diff line change @@ -134,15 +134,21 @@ def in_transaction?(connection = nil)
134134
135135 # Makes sure the provided block runs in a transaction. If we are not currently in a transaction, a new transaction is started.
136136 #
137+ # It mimics the ActiveRecord's +transaction+ method's API and actually uses it under the hood.
138+ #
139+ # However, the main difference is that it doesn't swallow +ActiveRecord::Rollback+ exception in case when there is no transaction open.
140+ #
141+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#method-i-transaction
142+ #
137143 # @param connection [ActiveRecord::ConnectionAdapters::AbstractAdapter] Database connection to operate in. Defaults to +ActiveRecord::Base.connection+
144+ # @param requires_new [Boolean] Forces creation of new subtransaction (savepoint) even if transaction is already opened.
145+ # @param new_tx_options [Hash<Symbol, void>] Options to be passed to +connection.transaction+ on new transaction creation
138146 # @return void
139- def in_transaction ( connection = nil )
140- connection ||= default_connection
141-
142- if in_transaction? ( connection )
147+ def in_transaction ( connection = default_connection , requires_new : false , **new_tx_options )
148+ if in_transaction? ( connection ) && !requires_new
143149 yield
144150 else
145- connection . transaction { yield }
151+ connection . transaction ( requires_new : requires_new , ** new_tx_options ) { yield }
146152 end
147153 end
148154
Original file line number Diff line number Diff line change 550550 end
551551 end
552552
553+ it "runs new transaction even inside existing transaction if requires_new is true" do
554+ outer_handler , inner_handler = spy ( "outter" ) , spy ( "inner" )
555+ expect ( ActiveRecord ::Base . connection . transaction_open? ) . to be_falsey
556+ ActiveRecord ::Base . transaction do
557+ expect ( ActiveRecord ::Base . connection . transaction_open? ) . to be_truthy
558+ described_class . after_commit { outer_handler . call }
559+ receiver . in_transaction ( requires_new : true ) do
560+ receiver . after_commit { inner_handler . call }
561+ raise ActiveRecord ::Rollback
562+ end
563+ end
564+ expect ( outer_handler ) . to have_received ( :call )
565+ expect ( inner_handler ) . not_to have_received ( :call )
566+ end
567+
553568 context "when rolling back, the rollback propogates to the parent transaction block" do
554569 subject { receiver . after_rollback { handler . call } }
555570
You can’t perform that action at this time.
0 commit comments