diff options
author | Eugene Kenny <elkenny@gmail.com> | 2018-05-10 00:24:04 +0100 |
---|---|---|
committer | Eugene Kenny <elkenny@gmail.com> | 2018-05-10 00:24:04 +0100 |
commit | 2f29380c18d7754cefffbc09bebaa2007fb99929 (patch) | |
tree | c99673f97154f4b5b8b667f7fae11b21b4ecb3a7 | |
parent | f507085fa2a7625324e6f4e3ecef9b27dabefb4f (diff) | |
download | rails-2f29380c18d7754cefffbc09bebaa2007fb99929.tar.gz rails-2f29380c18d7754cefffbc09bebaa2007fb99929.tar.bz2 rails-2f29380c18d7754cefffbc09bebaa2007fb99929.zip |
Don't clear transaction state after manual rollback
If an `ActiveRecord::Rollback` error was raised by a persistence method
(e.g. in an `after_save` callback), this logic would potentially discard
the original state of the record from before the transaction, preventing
it from being restored later when the transaction was rolled back.
-rw-r--r-- | activerecord/lib/active_record/transactions.rb | 8 | ||||
-rw-r--r-- | activerecord/test/cases/transactions_test.rb | 12 |
2 files changed, 13 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index be4f41050e..6e9dff5796 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -382,13 +382,7 @@ module ActiveRecord status = nil self.class.transaction do add_to_transaction - begin - status = yield - rescue ActiveRecord::Rollback - clear_transaction_record_state - status = nil - end - + status = yield raise ActiveRecord::Rollback unless status end status diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 3fd38b4b60..931e01845a 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -292,6 +292,18 @@ class TransactionTest < ActiveRecord::TestCase assert_nil new_topic.id, "The topic should not have an ID" end + def test_callback_rollback_in_create_with_rollback_exception + topic = Class.new(Topic) { + def after_create_for_transaction + raise ActiveRecord::Rollback + end + } + + new_topic = topic.create(title: "A new topic") + assert !new_topic.persisted?, "The topic should not be persisted" + assert_nil new_topic.id, "The topic should not have an ID" + end + def test_nested_explicit_transactions Topic.transaction do Topic.transaction do |