diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2018-05-19 10:10:18 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-19 10:10:18 +0900 |
commit | 870766017ab20541a1e3b10bf026d82522028028 (patch) | |
tree | cca7cff257f4d47ec7a0a6c02ccaec4835dc5687 | |
parent | 1efbc634b5707cfca1bec0cf39f90520396a979b (diff) | |
parent | 5359428a142239578b4d1dfb43dd8c417ab57b5c (diff) | |
download | rails-870766017ab20541a1e3b10bf026d82522028028.tar.gz rails-870766017ab20541a1e3b10bf026d82522028028.tar.bz2 rails-870766017ab20541a1e3b10bf026d82522028028.zip |
Merge pull request #32911 from eugeneius/finalize_transaction_record_state
Finalize transaction record state after real transaction
3 files changed, 54 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb index 0ce3796829..b59df2fff7 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb @@ -17,11 +17,19 @@ module ActiveRecord end def committed? - @state == :committed + @state == :committed || @state == :fully_committed + end + + def fully_committed? + @state == :fully_committed end def rolledback? - @state == :rolledback + @state == :rolledback || @state == :fully_rolledback + end + + def fully_rolledback? + @state == :fully_rolledback end def fully_completed? @@ -55,10 +63,19 @@ module ActiveRecord @state = :rolledback end + def full_rollback! + @children.each { |c| c.rollback! } + @state = :fully_rolledback + end + def commit! @state = :committed end + def full_commit! + @state = :fully_committed + end + def nullify! @state = nil end @@ -88,10 +105,6 @@ module ActiveRecord records << record end - def rollback - @state.rollback! - end - def rollback_records ite = records.uniq while record = ite.shift @@ -103,10 +116,6 @@ module ActiveRecord end end - def commit - @state.commit! - end - def before_commit_records records.uniq.each(&:before_committed!) if @run_commit_callbacks end @@ -145,12 +154,12 @@ module ActiveRecord def rollback connection.rollback_to_savepoint(savepoint_name) - super + @state.rollback! end def commit connection.release_savepoint(savepoint_name) - super + @state.commit! end def full_rollback?; false; end @@ -168,12 +177,12 @@ module ActiveRecord def rollback connection.rollback_db_transaction - super + @state.full_rollback! end def commit connection.commit_db_transaction - super + @state.full_commit! end end diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb index 20603aaf2d..ccb2d57b03 100644 --- a/activerecord/lib/active_record/transactions.rb +++ b/activerecord/lib/active_record/transactions.rb @@ -472,7 +472,8 @@ module ActiveRecord def update_attributes_from_transaction_state(transaction_state) if transaction_state && transaction_state.finalized? - restore_transaction_record_state if transaction_state.rolledback? + restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback? + force_clear_transaction_record_state if transaction_state.fully_committed? clear_transaction_record_state if transaction_state.fully_completed? end end diff --git a/activerecord/test/cases/transactions_test.rb b/activerecord/test/cases/transactions_test.rb index 17aeabe34e..0d7857c0cf 100644 --- a/activerecord/test/cases/transactions_test.rb +++ b/activerecord/test/cases/transactions_test.rb @@ -679,6 +679,35 @@ class TransactionTest < ActiveRecord::TestCase assert_not_predicate topic, :frozen? end + def test_restore_new_record_after_double_save + topic = Topic.new + + Topic.transaction do + topic.save! + topic.save! + raise ActiveRecord::Rollback + end + + assert_predicate topic, :new_record? + end + + def test_dont_restore_new_record_in_subsequent_transaction + topic = Topic.new + + Topic.transaction do + topic.save! + topic.save! + end + + Topic.transaction do + topic.save! + raise ActiveRecord::Rollback + end + + assert_predicate topic, :persisted? + assert_not_predicate topic, :new_record? + end + def test_restore_id_after_rollback topic = Topic.new |