diff options
author | eileencodes <eileencodes@gmail.com> | 2017-07-01 14:25:33 -0400 |
---|---|---|
committer | eileencodes <eileencodes@gmail.com> | 2017-07-01 14:53:30 -0400 |
commit | 0237da287eb4c507d10a0c6d94150093acc52b03 (patch) | |
tree | 4248673d4f498716ed057a74320d08311d579e8a /tasks | |
parent | 608ebccf8f6314c945444b400a37c2d07f21b253 (diff) | |
download | rails-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 'tasks')
0 files changed, 0 insertions, 0 deletions