class TransactionTest
Public Instance Methods
after_create_for_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 250 def after_create_for_transaction raise "Make the transaction rollback" end
setup()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 17 def setup @first, @second = Topic.find(1, 2).sort_by(&:id) end
test_add_to_null_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 63 def test_add_to_null_transaction topic = Topic.new topic.add_to_transaction end
test_assign_custom_primary_key_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 704 def test_assign_custom_primary_key_after_rollback movie = Movie.create!(name: "foo") Movie.transaction do movie.save! raise ActiveRecord::Rollback end movie.movieid = nil assert_nil movie.movieid end
test_assign_id_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 692 def test_assign_id_after_rollback topic = Topic.create! Topic.transaction do topic.save! raise ActiveRecord::Rollback end topic.id = nil assert_nil topic.id end
test_callback_rollback_in_create()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 248 def test_callback_rollback_in_create topic = Class.new(Topic) { def after_create_for_transaction raise "Make the transaction rollback" end } new_topic = topic.new(title: "A new topic", author_name: "Ben", author_email_address: "ben@example.com", written_on: "2003-07-16t15:28:11.2233+01:00", last_read: "2004-04-15", bonus_time: "2005-01-30t15:28:00.00+01:00", content: "Have a nice day", approved: false) new_record_snapshot = !new_topic.persisted? id_present = new_topic.has_attribute?(Topic.primary_key) id_snapshot = new_topic.id # Make sure the second save gets the after_create callback called. 2.times do new_topic.approved = true e = assert_raises(RuntimeError) { new_topic.save } assert_equal "Make the transaction rollback", e.message assert_equal new_record_snapshot, !new_topic.persisted?, "The topic should have its old persisted value" if id_snapshot.nil? assert_nil new_topic.id, "The topic should have its old id" else assert_equal id_snapshot, new_topic.id, "The topic should have its old id" end assert_equal id_present, new_topic.has_attribute?(Topic.primary_key) end end
test_callback_rollback_in_create_with_record_invalid_exception()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 283 def test_callback_rollback_in_create_with_record_invalid_exception topic = Class.new(Topic) { def after_create_for_transaction raise ActiveRecord::RecordInvalid.new(Author.new) 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
test_cancellation_from_before_destroy_rollbacks_in_destroy()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 211 def test_cancellation_from_before_destroy_rollbacks_in_destroy add_cancelling_before_destroy_with_db_side_effect_to_topic @first nbooks_before_destroy = Book.count status = @first.destroy assert !status @first.reload assert_equal nbooks_before_destroy, Book.count end
test_double_nested_transaction_applies_parent_state_on_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 351 def test_double_nested_transaction_applies_parent_state_on_rollback topic_one = Topic.new(title: "A new topic") topic_two = Topic.new(title: "Another new topic") topic_three = Topic.new(title: "Another new topic of course") Topic.transaction do topic_one.save Topic.transaction do topic_two.save Topic.transaction do topic_three.save end end assert_predicate topic_one, :persisted? assert_predicate topic_two, :persisted? assert_predicate topic_three, :persisted? raise ActiveRecord::Rollback end refute_predicate topic_one, :persisted? refute_predicate topic_two, :persisted? refute_predicate topic_three, :persisted? end
test_failing_on_exception()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 127 def test_failing_on_exception begin Topic.transaction do @first.approved = true @second.approved = false @first.save @second.save raise "Bad things!" end rescue # caught it end assert @first.approved?, "First should still be changed in the objects" assert !@second.approved?, "Second should still be changed in the objects" assert !Topic.find(1).approved?, "First shouldn't have been approved" assert Topic.find(2).approved?, "Second should still be approved" end
test_force_savepoint_in_nested_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 403 def test_force_savepoint_in_nested_transaction Topic.transaction do @first.approved = true @second.approved = false @first.save! @second.save! begin Topic.transaction requires_new: true do @first.happy = false @first.save! raise end rescue end end assert @first.reload.approved? assert !@second.reload.approved? end
test_force_savepoint_on_instance()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 424 def test_force_savepoint_on_instance @first.transaction do @first.approved = true @second.approved = false @first.save! @second.save! begin @second.transaction requires_new: true do @first.happy = false @first.save! raise end rescue end end assert @first.reload.approved? assert !@second.reload.approved? end
test_invalid_keys_for_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 396 def test_invalid_keys_for_transaction assert_raise ArgumentError do Topic.transaction nested: true do end end end
test_manually_rolling_back_a_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 379 def test_manually_rolling_back_a_transaction Topic.transaction do @first.approved = true @second.approved = false @first.save @second.save raise ActiveRecord::Rollback end assert @first.approved?, "First should still be changed in the objects" assert !@second.approved?, "Second should still be changed in the objects" assert !Topic.find(1).approved?, "First shouldn't have been approved" assert Topic.find(2).approved?, "Second should still be approved" end
test_many_savepoints()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 466 def test_many_savepoints Topic.transaction do @first.content = "One" @first.save! begin Topic.transaction requires_new: true do @first.content = "Two" @first.save! begin Topic.transaction requires_new: true do @first.content = "Three" @first.save! begin Topic.transaction requires_new: true do @first.content = "Four" @first.save! raise end rescue end @three = @first.reload.content raise end rescue end @two = @first.reload.content raise end rescue end @one = @first.reload.content end assert_equal "One", @one assert_equal "Two", @two assert_equal "Three", @three end
test_mark_transaction_state_as_committed()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 857 def test_mark_transaction_state_as_committed connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction transaction.rollback assert_equal :committed, transaction.state.commit! end
test_mark_transaction_state_as_nil()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 875 def test_mark_transaction_state_as_nil connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction transaction.commit assert_nil transaction.state.nullify! end
test_mark_transaction_state_as_rolledback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 866 def test_mark_transaction_state_as_rolledback connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction transaction.commit assert_equal :rolledback, transaction.state.rollback! end
test_nested_explicit_transactions()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 295 def test_nested_explicit_transactions Topic.transaction do Topic.transaction do @first.approved = true @second.approved = false @first.save @second.save end end assert Topic.find(1).approved?, "First should have been approved" assert !Topic.find(2).approved?, "Second should have been unapproved" end
test_nested_transaction_with_new_transaction_applies_parent_state_on_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 309 def test_nested_transaction_with_new_transaction_applies_parent_state_on_rollback topic_one = Topic.new(title: "A new topic") topic_two = Topic.new(title: "Another new topic") Topic.transaction do topic_one.save Topic.transaction(requires_new: true) do topic_two.save assert_predicate topic_one, :persisted? assert_predicate topic_two, :persisted? end raise ActiveRecord::Rollback end refute_predicate topic_one, :persisted? refute_predicate topic_two, :persisted? end
test_nested_transaction_without_new_transaction_applies_parent_state_on_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 330 def test_nested_transaction_without_new_transaction_applies_parent_state_on_rollback topic_one = Topic.new(title: "A new topic") topic_two = Topic.new(title: "Another new topic") Topic.transaction do topic_one.save Topic.transaction do topic_two.save assert_predicate topic_one, :persisted? assert_predicate topic_two, :persisted? end raise ActiveRecord::Rollback end refute_predicate topic_one, :persisted? refute_predicate topic_two, :persisted? end
test_no_savepoint_in_nested_transaction_without_force()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 445 def test_no_savepoint_in_nested_transaction_without_force Topic.transaction do @first.approved = true @second.approved = false @first.save! @second.save! begin Topic.transaction do @first.approved = false @first.save! raise end rescue end end assert !@first.reload.approved? assert !@second.reload.approved? end
test_number_of_transactions_in_commit()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 91 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
test_persisted_in_a_model_with_custom_primary_key_after_failed_save()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 21 def test_persisted_in_a_model_with_custom_primary_key_after_failed_save movie = Movie.create assert !movie.persisted? end
test_raise_after_destroy()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 26 def test_raise_after_destroy assert_not @first.frozen? assert_raises(RuntimeError) { Topic.transaction do @first.destroy assert @first.frozen? raise end } assert @first.reload assert_not @first.frozen? end
test_raising_exception_in_callback_rollbacks_in_save()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 147 def test_raising_exception_in_callback_rollbacks_in_save def @first.after_save_for_transaction raise "Make the transaction rollback" end @first.approved = true e = assert_raises(RuntimeError) { @first.save } assert_equal "Make the transaction rollback", e.message assert !Topic.find(1).approved? end
test_raising_exception_in_nested_transaction_restore_state_in_save()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 171 def test_raising_exception_in_nested_transaction_restore_state_in_save topic = Topic.new def topic.after_save_for_transaction raise "Make the transaction rollback" end assert_raises(RuntimeError) do Topic.transaction { topic.save } end assert topic.new_record?, "#{topic.inspect} should be new record" end
test_read_attribute_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 716 def test_read_attribute_after_rollback topic = Topic.new Topic.transaction do topic.save! raise ActiveRecord::Rollback end assert_nil topic.read_attribute(:id) end
test_read_attribute_with_custom_primary_key_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 727 def test_read_attribute_with_custom_primary_key_after_rollback movie = Movie.new(name: "foo") Movie.transaction do movie.save! raise ActiveRecord::Rollback end assert_nil movie.read_attribute(:movieid) end
test_releasing_named_savepoints()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 528 def test_releasing_named_savepoints Topic.transaction do Topic.connection.create_savepoint("another") Topic.connection.release_savepoint("another") # The savepoint is now gone and we can't remove it again. assert_raises(ActiveRecord::StatementInvalid) do Topic.connection.release_savepoint("another") end end end
test_restore_active_record_state_for_all_records_in_a_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 617 def test_restore_active_record_state_for_all_records_in_a_transaction topic_without_callbacks = Class.new(ActiveRecord::Base) do self.table_name = "topics" end topic_1 = Topic.new(title: "test_1") topic_2 = Topic.new(title: "test_2") topic_3 = topic_without_callbacks.new(title: "test_3") Topic.transaction do assert topic_1.save assert topic_2.save assert topic_3.save @first.save @second.destroy assert topic_1.persisted?, "persisted" assert_not_nil topic_1.id assert topic_2.persisted?, "persisted" assert_not_nil topic_2.id assert topic_3.persisted?, "persisted" assert_not_nil topic_3.id assert @first.persisted?, "persisted" assert_not_nil @first.id assert @second.destroyed?, "destroyed" raise ActiveRecord::Rollback end assert !topic_1.persisted?, "not persisted" assert_nil topic_1.id assert !topic_2.persisted?, "not persisted" assert_nil topic_2.id assert !topic_3.persisted?, "not persisted" assert_nil topic_3.id assert @first.persisted?, "persisted" assert_not_nil @first.id assert !@second.destroyed?, "not destroyed" end
test_restore_custom_primary_key_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 681 def test_restore_custom_primary_key_after_rollback movie = Movie.new(name: "foo") Movie.transaction do movie.save! raise ActiveRecord::Rollback end assert_nil movie.movieid end
test_restore_frozen_state_after_double_destroy()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 655 def test_restore_frozen_state_after_double_destroy topic = Topic.create reply = topic.replies.create Topic.transaction do topic.destroy # calls #destroy on reply (since dependent: destroy) reply.destroy raise ActiveRecord::Rollback end assert_not reply.frozen? assert_not topic.frozen? end
test_restore_id_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 670 def test_restore_id_after_rollback topic = Topic.new Topic.transaction do topic.save! raise ActiveRecord::Rollback end assert_nil topic.id end
test_rollback_for_freshly_persisted_records()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 771 def test_rollback_for_freshly_persisted_records topic = Topic.create Topic.transaction do topic.destroy raise ActiveRecord::Rollback end assert topic.persisted?, "persisted" end
test_rollback_of_frozen_records()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 762 def test_rollback_of_frozen_records topic = Topic.create.freeze Topic.transaction do topic.destroy raise ActiveRecord::Rollback end assert topic.frozen?, "frozen" end
test_rollback_when_commit_raises()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 560 def test_rollback_when_commit_raises assert_called(Topic.connection, :begin_db_transaction) do Topic.connection.stub(:commit_db_transaction, -> { raise("OH NOES") }) do assert_called(Topic.connection, :rollback_db_transaction) do e = assert_raise RuntimeError do Topic.transaction do # do nothing end end assert_equal "OH NOES", e.message end end end end
test_rollback_when_saving_a_frozen_record()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 576 def test_rollback_when_saving_a_frozen_record topic = Topic.new(title: "test") topic.freeze e = assert_raise(RuntimeError) { topic.save } # Not good enough, but we can't do much # about it since there is no specific error # for frozen objects. assert_match(/frozen/i, e.message) assert !topic.persisted?, "not persisted" assert_nil topic.id assert topic.frozen?, "not frozen" end
test_rollback_when_thread_killed()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 589 def test_rollback_when_thread_killed return if in_memory_db? queue = Queue.new thread = Thread.new do Topic.transaction do @first.approved = true @second.approved = false @first.save queue.push nil sleep @second.save end end queue.pop thread.kill thread.join assert @first.approved?, "First should still be changed in the objects" assert !@second.approved?, "Second should still be changed in the objects" assert !Topic.find(1).approved?, "First shouldn't have been approved" assert Topic.find(2).approved?, "Second should still be approved" end
test_rolling_back_in_a_callback_rollbacks_before_save()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 158 def test_rolling_back_in_a_callback_rollbacks_before_save def @first.before_save_for_transaction raise ActiveRecord::Rollback end assert !@first.approved Topic.transaction do @first.approved = true @first.save! end assert !Topic.find(@first.id).approved?, "Should not commit the approved flag" end
test_savepoints_name()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 540 def test_savepoints_name Topic.transaction do assert_nil Topic.connection.current_savepoint_name assert_nil Topic.connection.current_transaction.savepoint_name Topic.transaction(requires_new: true) do assert_equal "active_record_1", Topic.connection.current_savepoint_name assert_equal "active_record_1", Topic.connection.current_transaction.savepoint_name Topic.transaction(requires_new: true) do assert_equal "active_record_2", Topic.connection.current_savepoint_name assert_equal "active_record_2", Topic.connection.current_transaction.savepoint_name end assert_equal "active_record_1", Topic.connection.current_savepoint_name assert_equal "active_record_1", Topic.connection.current_transaction.savepoint_name end end end
test_set_state_method_is_deprecated()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 846 def test_set_state_method_is_deprecated connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction transaction.commit assert_deprecated do transaction.state.set_state(:rolledback) end end
test_sqlite_add_column_in_transaction()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 780 def test_sqlite_add_column_in_transaction return true unless current_adapter?(:SQLite3Adapter) # Test first if column creation/deletion works correctly when no # transaction is in place. # # We go back to the connection for the column queries because # Topic.columns is cached and won't report changes to the DB assert_nothing_raised do Topic.reset_column_information Topic.connection.add_column("topics", "stuff", :string) assert_includes Topic.column_names, "stuff" Topic.reset_column_information Topic.connection.remove_column("topics", "stuff") assert_not_includes Topic.column_names, "stuff" end if Topic.connection.supports_ddl_transactions? assert_nothing_raised do Topic.transaction { Topic.connection.add_column("topics", "stuff", :string) } end else Topic.transaction do assert_raise(ActiveRecord::StatementInvalid) { Topic.connection.add_column("topics", "stuff", :string) } raise ActiveRecord::Rollback end end ensure begin Topic.connection.remove_column("topics", "stuff") rescue ensure Topic.reset_column_information end end
test_successful()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 41 def test_successful Topic.transaction do @first.approved = true @second.approved = false @first.save @second.save end assert Topic.find(1).approved?, "First should have been approved" assert !Topic.find(2).approved?, "Second should have been unapproved" end
test_successful_with_instance_method()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 115 def test_successful_with_instance_method @first.transaction do @first.approved = true @second.approved = false @first.save @second.save end assert Topic.find(1).approved?, "First should have been approved" assert !Topic.find(2).approved?, "Second should have been unapproved" end
test_successful_with_return()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 68 def test_successful_with_return committed = false Topic.connection.class_eval do alias :real_commit_db_transaction :commit_db_transaction define_method(:commit_db_transaction) do committed = true real_commit_db_transaction end end transaction_with_return assert committed assert Topic.find(1).approved?, "First should have been approved" assert !Topic.find(2).approved?, "Second should have been unapproved" ensure Topic.connection.class_eval do remove_method :commit_db_transaction alias :commit_db_transaction :real_commit_db_transaction rescue nil end end
test_transaction_rollback_with_primarykeyless_tables()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 884 def test_transaction_rollback_with_primarykeyless_tables connection = ActiveRecord::Base.connection connection.create_table(:transaction_without_primary_keys, force: true, id: false) do |t| t.integer :thing_id end klass = Class.new(ActiveRecord::Base) do self.table_name = "transaction_without_primary_keys" after_commit {} # necessary to trigger the has_transactional_callbacks branch end assert_no_difference(-> { klass.count }) do ActiveRecord::Base.transaction do klass.create! raise ActiveRecord::Rollback end end ensure connection.drop_table "transaction_without_primary_keys", if_exists: true end
test_transaction_state_is_cleared_when_record_is_persisted()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 185 def test_transaction_state_is_cleared_when_record_is_persisted author = Author.create! name: "foo" author.name = nil assert_not author.save assert_not author.new_record? end
test_transactions_state_from_commit()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 832 def test_transactions_state_from_commit connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction assert transaction.open? assert !transaction.state.rolledback? assert !transaction.state.committed? transaction.commit assert !transaction.state.rolledback? assert transaction.state.committed? end
test_transactions_state_from_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 818 def test_transactions_state_from_rollback connection = Topic.connection transaction = ActiveRecord::ConnectionAdapters::TransactionManager.new(connection).begin_transaction assert transaction.open? assert !transaction.state.rolledback? assert !transaction.state.committed? transaction.rollback assert transaction.state.rolledback? assert !transaction.state.committed? end
test_update_should_rollback_on_failure()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 192 def test_update_should_rollback_on_failure author = Author.find(1) posts_count = author.posts.size assert posts_count > 0 status = author.update(name: nil, post_ids: []) assert !status assert_equal posts_count, author.posts.reload.size end
test_update_should_rollback_on_failure!()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 201 def test_update_should_rollback_on_failure! author = Author.find(1) posts_count = author.posts.size assert posts_count > 0 assert_raise(ActiveRecord::RecordInvalid) do author.update!(name: nil, post_ids: []) end assert_equal posts_count, author.posts.reload.size end
test_using_named_savepoints()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 510 def test_using_named_savepoints Topic.transaction do @first.approved = true @first.save! Topic.connection.create_savepoint("first") @first.approved = false @first.save! Topic.connection.rollback_to_savepoint("first") assert @first.reload.approved? @first.approved = false @first.save! Topic.connection.release_savepoint("first") assert_not @first.reload.approved? end end
test_write_attribute_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 738 def test_write_attribute_after_rollback topic = Topic.create! Topic.transaction do topic.save! raise ActiveRecord::Rollback end topic.write_attribute(:id, nil) assert_nil topic.id end
test_write_attribute_with_custom_primary_key_after_rollback()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 750 def test_write_attribute_with_custom_primary_key_after_rollback movie = Movie.create!(name: "foo") Movie.transaction do movie.save! raise ActiveRecord::Rollback end movie.write_attribute(:movieid, nil) assert_nil movie.movieid end
transaction_with_return()
click to toggle source
# File activerecord/test/cases/transactions_test.rb, line 53 def transaction_with_return Topic.transaction do @first.approved = true @second.approved = false @first.save @second.save return end end