How to exclude a model from a transaction in ActiveRecord?

I have a special case of Model, which should not be part of an external transaction:

Outer.Transaction do
  ...

  Inner.create(:blah)

  ...
end

How to stop Inner, becoming part of a transaction, assuming that Inner should not know anything about which specific transaction it is pulling?

For example, creating an internal transaction is not, because it will also become part of the external transaction.

I want to do this because the internal model must write immediately and not wait for the external transaction to complete.

+1
source share
2 answers

I'm curious what will require such a design!

, , - , . , mysql Inner , (, MyIsam), -, (YUK!).

, Inner.create . , , . - :

create_inner = false
begin
  Outer.transaction.do
    ...
    create_inner = true # instead of Inner.create(:blah)
    ...
  end
ensure
  if create_inner
    Inner.create(:blah)
  end
end

, Inner. , created_inner false , , , , .

, Inner , Inner. after_create Inner. Inner.create , , , , . :

class Inner < ActiveRecord::Base

  def self.ensure_created(&block)
    Thread.current[:created_inner] = false        
    begin
      block.call
    rescue => e
      if Thread.current[:created_inner]
        Inner.create(:blah)
      end
      raise e
    end
  end

  def after_create
    # Flag that an instance has been created in this thread so
    # that if we rollback out of a transaction we can create again
    Thread.current[:created_inner] = true
  end

:

Inner.ensure_created do
  Outer.transaction do
    ...
    Inner.create(:blah)
    ...
  end
end

, , , . . , ActiveRecord:: Rollback , Outer.transaction, , Inner . , . , , - !

+1

Inner, .

0

All Articles