Last active
November 21, 2015 12:04
-
-
Save alcedo/a118822e290e3d6cbf61 to your computer and use it in GitHub Desktop.
Rails Transaction Demonstration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe 'Rails Transaction Demonstration' do | |
it 'Should rollback due to any exception raised' do | |
expect { | |
ActiveRecord::Base.transaction do | |
NotificationHistory.create!(transporter: 'should not see this') | |
Resource.create(name: 'should not see this') | |
NotificationHistory.first.transporter = 'should not see this' | |
NotificationHistory.first.save! | |
raise 'should not have create / saves persisting' | |
end | |
}.to raise_error | |
NotificationHistory.count.should == 0 | |
Resource.count.should == 0 | |
end | |
context 'Special case of ActiveRecord::Rollback exception' do | |
it 'Creates objects even though Rollback is triggered in inner txn' do | |
# this is created | |
NotificationHistory.create!(transporter: 'first') | |
expect { | |
ActiveRecord::Base.transaction do | |
# this is created, inner transaction rollback doesnt affect at all | |
NotificationHistory.create!(transporter: 'This is created') | |
ActiveRecord::Base.transaction do | |
# this is created, inner transaction rollback doesnt affect at all | |
NotificationHistory.create!(transporter: 'Inner transporter') | |
raise ActiveRecord::Rollback | |
end | |
end | |
}.to_not raise_error | |
# 3 Objects created, reason is the ActiveRecord::Rollback exception in the nested block does not issue a ROLLBACK. | |
# Since these exceptions are captured in transaction blocks, | |
# the parent block does not see it and the real transaction is committed. | |
NotificationHistory.count.should == 3 | |
end | |
it 'Creates only parent objects when RollBack is triggered in inner txn' do | |
# this is created | |
NotificationHistory.create!(transporter: 'first') | |
expect { | |
ActiveRecord::Base.transaction do | |
# this is created, inner transaction rollback doesnt affect parent | |
NotificationHistory.create!(transporter: 'This is created') | |
ActiveRecord::Base.transaction(requires_new: true) do | |
# not created! | |
NotificationHistory.create!(transporter: 'Inner transporter') | |
raise ActiveRecord::Rollback | |
end | |
end | |
}.to_not raise_error | |
# only 2 objects created. In order to get a ROLLBACK for the nested transaction you may ask for a real | |
# sub-transaction by passing requires_new: true. If anything goes wrong, | |
# the database rolls back to the beginning of the sub-transaction without rolling back the parent transaction. | |
NotificationHistory.count.should == 2 | |
NotificationHistory.first.transporter.should == 'first' | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment