Should take the record's state of first action in the transaction
If the same id's records are saved and/or destroyed in the transaction,
commit callbackes will only run for the first enrolled record.
a023e21800/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb (L115-L119)
The regression #36132 is caused due to #35920 changed the enrollment
order that the first action's record will be enrolled to last in the
transaction.
We could not change the the enrollment order as long as someone depends
on the enrollment order.
Fixes #36132.
This commit is contained in:
parent
c1ff1392db
commit
e0a315b38a
@ -333,7 +333,7 @@ def before_committed! # :nodoc:
|
||||
# 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:
|
||||
if should_run_callbacks && (destroyed? || persisted?)
|
||||
if should_run_callbacks && trigger_transactional_callbacks?
|
||||
@_committed_already_called = true
|
||||
_run_commit_without_transaction_enrollment_callbacks
|
||||
_run_commit_callbacks
|
||||
@ -346,7 +346,7 @@ def committed!(should_run_callbacks: true) #:nodoc:
|
||||
# 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:
|
||||
if should_run_callbacks
|
||||
if should_run_callbacks && trigger_transactional_callbacks?
|
||||
_run_rollback_callbacks
|
||||
_run_rollback_without_transaction_enrollment_callbacks
|
||||
end
|
||||
@ -364,7 +364,9 @@ def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
|
||||
def with_transaction_returning_status
|
||||
status = nil
|
||||
self.class.transaction do
|
||||
unless has_transactional_callbacks?
|
||||
if has_transactional_callbacks?
|
||||
add_to_transaction
|
||||
else
|
||||
sync_with_transaction_state if @transaction_state&.finalized?
|
||||
@transaction_state = self.class.connection.transaction_state
|
||||
end
|
||||
@ -372,11 +374,6 @@ def with_transaction_returning_status
|
||||
|
||||
status = yield
|
||||
raise ActiveRecord::Rollback unless status
|
||||
ensure
|
||||
if has_transactional_callbacks? &&
|
||||
(@_new_record_before_last_commit && !new_record? || _trigger_update_callback || _trigger_destroy_callback)
|
||||
add_to_transaction
|
||||
end
|
||||
end
|
||||
status
|
||||
end
|
||||
@ -460,6 +457,10 @@ def add_to_transaction
|
||||
self.class.connection.add_transaction_record(self)
|
||||
end
|
||||
|
||||
def trigger_transactional_callbacks?
|
||||
@_new_record_before_last_commit && !new_record? || _trigger_update_callback || _trigger_destroy_callback
|
||||
end
|
||||
|
||||
def has_transactional_callbacks?
|
||||
!_rollback_callbacks.empty? || !_commit_callbacks.empty? || !_before_commit_callbacks.empty?
|
||||
end
|
||||
|
@ -36,6 +36,8 @@ class TopicWithCallbacks < ActiveRecord::Base
|
||||
|
||||
has_many :replies, class_name: "ReplyWithCallbacks", foreign_key: "parent_id"
|
||||
|
||||
before_destroy { self.class.find(id).touch if persisted? }
|
||||
|
||||
before_commit { |record| record.do_before_commit(nil) }
|
||||
after_commit { |record| record.do_after_commit(nil) }
|
||||
after_save_commit { |record| record.do_after_commit(:save) }
|
||||
|
Loading…
Reference in New Issue
Block a user