aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-04-16 08:11:59 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-04-16 08:26:58 +0900
commitf7e126beae6249ad75d94bc585f53234b8ae5016 (patch)
tree6ba56eeb291078b9c260ac8f88ac463af5ed3e3e
parent60afbfffdcdb4510deccf8d6db303dd4260e3dc7 (diff)
downloadrails-f7e126beae6249ad75d94bc585f53234b8ae5016.tar.gz
rails-f7e126beae6249ad75d94bc585f53234b8ae5016.tar.bz2
rails-f7e126beae6249ad75d94bc585f53234b8ae5016.zip
Don't refer `@transaction_state` directly
Since 8180c39, remaining transaction state is cleared in `force_clear_transaction_record_state` to less work `sync_with_transaction_state`. But it caused a race condition that `@transaction_state` would be cleared by other threads if the state is finalized. To work as before, snapshot `@transaction_state` to local variable not to refer `@transaction_state` directly. Fixes #35983.
-rw-r--r--activerecord/lib/active_record/transactions.rb10
1 files changed, 5 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 634dc50376..03a373f0af 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -472,13 +472,13 @@ module ActiveRecord
# the TransactionState, and rolls back or commits the Active Record object
# as appropriate.
def sync_with_transaction_state
- if @transaction_state && @transaction_state.finalized?
- if @transaction_state.fully_committed?
+ if (transaction_state = @transaction_state)&.finalized?
+ if transaction_state.fully_committed?
force_clear_transaction_record_state
- elsif @transaction_state.committed?
+ elsif transaction_state.committed?
clear_transaction_record_state
- elsif @transaction_state.rolledback?
- force_restore_state = @transaction_state.fully_rolledback?
+ elsif transaction_state.rolledback?
+ force_restore_state = transaction_state.fully_rolledback?
restore_transaction_record_state(force_restore_state)
clear_transaction_record_state
end