Skip to content

Instantly share code, notes, and snippets.

@alcedo
Last active November 21, 2015 12:04
Show Gist options
  • Save alcedo/a118822e290e3d6cbf61 to your computer and use it in GitHub Desktop.
Save alcedo/a118822e290e3d6cbf61 to your computer and use it in GitHub Desktop.
Rails Transaction Demonstration
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