From f7e126beae6249ad75d94bc585f53234b8ae5016 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 16 Apr 2019 08:11:59 +0900 Subject: [PATCH] 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. --- activerecord/lib/active_record/transactions.rb | 10 +++++----- 1 file 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