Skip to content

Execute irreversible actions only when transactions are not rolled back

Notifications You must be signed in to change notification settings

goatapp/ar_after_transaction

 
 

Repository files navigation

Gem Version CI

Do something only after the currently open transactions have finished.

Normally everything gets rolled back when a transaction fails, but you cannot roll back sending an email or adding a job to Resque.

Install

gem install ar_after_transaction

Usage

just-in-time callbacks

class User
  after_create :do_stuff, :oops

  def do_stuff
    after_transaction do
      send_an_email # cannot be rolled back
    end
    comments.create(...) # will be rolled back
  end

  def oops
    raise "do the rolback!"
  end
end

General 'this should be rolled back when in a transaction' code like jobs

class Resque
  def revertable_enqueue(*args)
    ActiveRecord::Base.after_transaction do
      enqueue(*args)
    end
  end
end

When not in a transaction

after_transaction will perform the given block immediately

Transactional fixtures <-> normally_open_transactions

after_transaction assumes zero open transactions.
If you use transactional fixtures you should change it in test mode.

Rspec:

# spec/rails_helper.rb
  config.before(:suite) do
    ActiveRecord::Base.normally_open_transactions = 1
  end

Rails 3: after_commit hook can replace the first usage example:

class User
  after_commit :send_an_email on: :create
  after_create :do_stuff, :oops
  ...
end

Alternative

Rails 3+

  • basic support is built in, use it if you can!
  • after_commit :foo
  • after_commit :bar, on: :create / :update
  • after_commit everywhere

after_commit

  • pro: threadsafe
  • pro: more fine-grained callbacks (before_commit, after_commit, before_rollback, after_rollback)
  • con: doesn't let you define after_transaction callbacks anywhere like ar_after_transaction does (outside of the after_commit, etc. callbacks which only happen at certain points in the model's life cycle)
  • con: more complex

Authors

Original idea and code from Jamis Buck (post by Jeremy Kemper)

Michael Grosser
michael@grosser.it
License: MIT

About

Execute irreversible actions only when transactions are not rolled back

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 100.0%