aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/transactions.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/transactions.rb')
-rw-r--r--activerecord/lib/active_record/transactions.rb64
1 files changed, 30 insertions, 34 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 45bc10b9b0..dd405c7796 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -2,24 +2,12 @@ module ActiveRecord
# See ActiveRecord::Transactions::ClassMethods for documentation.
module Transactions
extend ActiveSupport::Concern
+ #:nodoc:
ACTIONS = [:create, :destroy, :update]
- CALLBACK_WARN_MESSAGE = "Currently, Active Record suppresses errors raised " \
- "within `after_rollback`/`after_commit` callbacks and only print them to " \
- "the logs. In the next version, these errors will no longer be suppressed. " \
- "Instead, the errors will propagate normally just like in other Active " \
- "Record callbacks.\n" \
- "\n" \
- "You can opt into the new behavior and remove this warning by setting:\n" \
- "\n" \
- " config.active_record.raise_in_transactional_callbacks = true"
included do
define_callbacks :commit, :rollback,
- terminator: ->(_, result) { result == false },
scope: [:kind, :name]
-
- mattr_accessor :raise_in_transactional_callbacks, instance_writer: false
- self.raise_in_transactional_callbacks = false
end
# = Active Record Transactions
@@ -235,9 +223,6 @@ module ActiveRecord
def after_commit(*args, &block)
set_options_for_callbacks!(args)
set_callback(:commit, :after, *args, &block)
- unless ActiveRecord::Base.raise_in_transactional_callbacks
- ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
- end
end
# This callback is called after a create, update, or destroy are rolled back.
@@ -246,9 +231,16 @@ module ActiveRecord
def after_rollback(*args, &block)
set_options_for_callbacks!(args)
set_callback(:rollback, :after, *args, &block)
- unless ActiveRecord::Base.raise_in_transactional_callbacks
- ActiveSupport::Deprecation.warn(CALLBACK_WARN_MESSAGE)
- end
+ end
+
+ def raise_in_transactional_callbacks
+ ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks is deprecated and will be removed without replacement.')
+ true
+ end
+
+ def raise_in_transactional_callbacks=(value)
+ ActiveSupport::Deprecation.warn('ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement.')
+ value
end
private
@@ -265,7 +257,7 @@ module ActiveRecord
def assert_valid_transaction_action(actions)
if (actions - ACTIONS).any?
- raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS.join(",")}"
+ raise ArgumentError, ":on conditions for after_commit and after_rollback callbacks have to be one of #{ACTIONS}"
end
end
end
@@ -308,16 +300,16 @@ module ActiveRecord
#
# Ensure that it is not called if the object was never persisted (failed create),
# but call it after the commit of a destroyed object.
- def committed!(should_run_callbacks = true) #:nodoc:
- run_callbacks :commit if should_run_callbacks && destroyed? || persisted?
+ def committed!(should_run_callbacks: true) #:nodoc:
+ _run_commit_callbacks if should_run_callbacks && destroyed? || persisted?
ensure
force_clear_transaction_record_state
end
# Call the +after_rollback+ callbacks. The +force_restore_state+ argument indicates if the record
# state should be rolled back to the beginning or just to the last savepoint.
- def rolledback!(force_restore_state = false, should_run_callbacks = true) #:nodoc:
- run_callbacks :rollback if should_run_callbacks
+ def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
+ _run_rollback_callbacks if should_run_callbacks
ensure
restore_transaction_record_state(force_restore_state)
clear_transaction_record_state
@@ -326,9 +318,12 @@ module ActiveRecord
# Add the record to the current transaction so that the +after_rollback+ and +after_commit+ callbacks
# can be called.
def add_to_transaction
- if self.class.connection.add_transaction_record(self)
- remember_transaction_record_state
+ if has_transactional_callbacks?
+ self.class.connection.add_transaction_record(self)
+ else
+ set_transaction_state(self.class.connection.transaction_state)
end
+ remember_transaction_record_state
end
# Executes +method+ within a transaction and captures its return value as a
@@ -358,14 +353,12 @@ module ActiveRecord
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def remember_transaction_record_state #:nodoc:
@_start_transaction_state[:id] = id
- unless @_start_transaction_state.include?(:new_record)
- @_start_transaction_state[:new_record] = @new_record
- end
- unless @_start_transaction_state.include?(:destroyed)
- @_start_transaction_state[:destroyed] = @destroyed
- end
+ @_start_transaction_state.reverse_merge!(
+ new_record: @new_record,
+ destroyed: @destroyed,
+ frozen?: frozen?,
+ )
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
- @_start_transaction_state[:frozen?] = frozen?
end
# Clear the new record state and id of a record.
@@ -388,7 +381,10 @@ module ActiveRecord
thaw unless restore_state[:frozen?]
@new_record = restore_state[:new_record]
@destroyed = restore_state[:destroyed]
- write_attribute(self.class.primary_key, restore_state[:id])
+ pk = self.class.primary_key
+ if pk && read_attribute(pk) != restore_state[:id]
+ write_attribute(pk, restore_state[:id])
+ end
end
end
end