From 0002954512364f2f69d28798f7a79aa8e27d7b6b Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Fri, 8 Aug 2014 15:37:38 -0400 Subject: Use *_transaction methods in TransactionManager Use `commit_transaction`/`rollback_transaction` on `within_new_transaction` method, so they make sure they `pop` the transaction from the stack before calling the methods `commit`/`rollback`. --- .../connection_adapters/abstract/transaction.rb | 6 ++---- activerecord/test/cases/transactions_test.rb | 24 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb index 4a7f2aaca8..3fce32211d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb @@ -169,16 +169,14 @@ module ActiveRecord transaction = begin_transaction options yield rescue Exception => error - transaction.rollback if transaction + rollback_transaction if transaction raise ensure begin - transaction.commit unless error + commit_transaction unless error rescue Exception transaction.rollback raise - ensure - @stack.pop if transaction end end diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index b4849222b8..9cfe041de2 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -80,6 +80,30 @@ class TransactionTest < ActiveRecord::TestCase end end + def test_number_of_transactions_in_commit + num = nil + + Topic.connection.class_eval do + alias :real_commit_db_transaction :commit_db_transaction + define_method(:commit_db_transaction) do + num = transaction_manager.open_transactions + real_commit_db_transaction + end + end + + Topic.transaction do + @first.approved = true + @first.save! + end + + assert_equal 0, num + ensure + Topic.connection.class_eval do + remove_method :commit_db_transaction + alias :commit_db_transaction :real_commit_db_transaction rescue nil + end + end + def test_successful_with_instance_method @first.transaction do @first.approved = true -- cgit v1.2.3 From 2e90fe736de73cfd89eed68b38e03eb6175314bc Mon Sep 17 00:00:00 2001 From: Arthur Neves Date: Fri, 8 Aug 2014 15:46:00 -0400 Subject: Fix regression on after_commit in nested transactions. after_commit should not run in nested transactions, however they should run once the outermost transaction gets committed. This patch fixes the problem copying the records from the Savepoint to its parent. So the RealTransaction will have all records that needs to run callbacks on it. [fixes #16425] --- activerecord/CHANGELOG.md | 6 ++++++ .../connection_adapters/abstract/transaction.rb | 2 ++ activerecord/test/cases/transaction_callbacks_test.rb | 13 +++++++++++++ 3 files changed, 21 insertions(+) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 7d7870fe13..02660ae4c2 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,9 @@ +* Fix regression on after_commit that didnt fire when having nested transactions. + + Fixes #16425 + + *arthurnn* + * Do not try to write timestamps when a table has no timestamps columns. Fixes #8813. diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb index 3fce32211d..8f06cf3a1f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb @@ -111,6 +111,8 @@ module ActiveRecord def commit super connection.release_savepoint(savepoint_name) + parent = connection.transaction_manager.current_transaction + records.each { |r| parent.add_record(r) } end def full_rollback?; false; end diff --git a/activerecord/test/cases/transaction_callbacks_test.rb b/activerecord/test/cases/transaction_callbacks_test.rb index 3d64ecb464..a3f39804b7 100644 --- a/activerecord/test/cases/transaction_callbacks_test.rb +++ b/activerecord/test/cases/transaction_callbacks_test.rb @@ -129,6 +129,19 @@ class TransactionCallbacksTest < ActiveRecord::TestCase assert_equal [:commit_on_update], @first.history end + def test_only_call_after_commit_on_top_level_transactions + @first.after_commit_block{|r| r.history << :after_commit} + assert @first.history.empty? + + @first.transaction do + @first.transaction(requires_new: true) do + @first.touch + end + assert @first.history.empty? + end + assert_equal [:after_commit], @first.history + end + def test_call_after_rollback_after_transaction_rollsback @first.after_commit_block{|r| r.history << :after_commit} @first.after_rollback_block{|r| r.history << :after_rollback} -- cgit v1.2.3