aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/transactions.rb
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2017-07-01 14:25:33 -0400
committereileencodes <eileencodes@gmail.com>2017-07-01 14:53:30 -0400
commit0237da287eb4c507d10a0c6d94150093acc52b03 (patch)
tree4248673d4f498716ed057a74320d08311d579e8a /activerecord/lib/active_record/transactions.rb
parent608ebccf8f6314c945444b400a37c2d07f21b253 (diff)
downloadrails-0237da287eb4c507d10a0c6d94150093acc52b03.tar.gz
rails-0237da287eb4c507d10a0c6d94150093acc52b03.tar.bz2
rails-0237da287eb4c507d10a0c6d94150093acc52b03.zip
Apply record state based on parent transaction state
Let's say you have a nested transaction and both records are saved. Before the outer transaction closes, a rollback is performed. Previously the record in the outer transaction would get marked as not persisted but the inner transaction would get persisted. ```ruby Post.transaction do post_one.save # will get rolled back Post.transaction(requires_new: true) do post_two.save # incorrectly remains marked as persisted end raise ActiveRecord::Rollback end ``` To fix this the PR changes transaction handling to have the child transaction ask the parent how the records should be marked. When there are child transactions, it will always be a SavpointTransaction because the stack isn't empty. From there we pass the parent_transaction to the child SavepointTransaction where we add the children to the parent so the parent can mark the inner transaction as rolledback and thus mark the record as not persisted. `update_attributes_from_transaction_state` uses the `completed?` check to correctly mark all the transactions as rolledback and the inner record as not persisted. ```ruby Post.transaction do post_one.save # will get rolled back Post.transaction(requires_new: true) do post_two.save # with new behavior, correctly marked as not persisted on rollback end raise ActiveRecord::Rollback end ``` Fixes #29320
Diffstat (limited to 'activerecord/lib/active_record/transactions.rb')
-rw-r--r--activerecord/lib/active_record/transactions.rb2
1 files changed, 1 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 45795fa287..463bb1f314 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -490,7 +490,7 @@ module ActiveRecord
def update_attributes_from_transaction_state(transaction_state)
if transaction_state && transaction_state.finalized?
restore_transaction_record_state if transaction_state.rolledback?
- clear_transaction_record_state
+ clear_transaction_record_state if transaction_state.fully_completed?
end
end
end