outside_transaction
Makes sure the given block is only executed when not inside a transaction. If there is an open transaction it will be executed after the next successful commit or not executed at all if there is a rollback or failure.
This is useful when you're notifying another process. If the other process starts processing the message before the transaction is actually committed, it will not see your uncommitted changes as transactions are isolated (usually).
In the example below, if there is a lot of work after saving and
article, and ArticleEmailSender
is started too soon, it will not find
the article you just inserted.
Example:
class Article
after_create :send_emails
def send_emails
outside_transaction do
Resque.enqueue(ArticleEmailSender, id) # notifies another process
end
end
end
This example is using Resque.
Testing
rake
Testing your app
When testing your Rails app with use_transactional_fixtures
on
(meaning that all your tests are wrapped in a transaction that is rolled
back after the test), you need to disbale OutsideTransaction
, otherwise
your blocks wrapped in outside_transaction
will not be run.
Example for RSpec:
# spec/spec_helper.rb
RSpec.configure do |config|
config.before(:each) do
OutsideTransaction.disable
end
end