aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Kenny <elkenny@gmail.com>2018-05-10 00:24:04 +0100
committerEugene Kenny <elkenny@gmail.com>2018-05-10 00:24:04 +0100
commit2f29380c18d7754cefffbc09bebaa2007fb99929 (patch)
treec99673f97154f4b5b8b667f7fae11b21b4ecb3a7
parentf507085fa2a7625324e6f4e3ecef9b27dabefb4f (diff)
downloadrails-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.rb8
-rw-r--r--activerecord/test/cases/transactions_test.rb12
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