Module: Barricade::ClassMethods

Defined in:
lib/barricade.rb

Overview

Methods defined here are included as class methods on ActiveRecord::Base.

Instance Method Summary collapse

Instance Method Details

#locked_objectsObject

:nodoc:



76
77
78
# File 'lib/barricade.rb', line 76

def locked_objects #:nodoc:
  @locked_objects || []
end

#locked_objects=(objects) ⇒ Object

:nodoc:



72
73
74
# File 'lib/barricade.rb', line 72

def locked_objects=(objects) #:nodoc:
  @locked_objects = objects
end

#transaction_with_locks(*objects) ⇒ Object

Perform a transaction with the given ActiveRecord objects locked.

e.g.

Post.transaction_with_locks(post) do
  post.comments.create!(...)
end

Raises:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/barricade.rb', line 41

def transaction_with_locks(*objects)
  objects = objects.flatten.compact
  return if objects.all? {|object| ActiveRecord::Base.locked_objects.include?(object) }

  minimum_transaction_level = Barricade.configuration.running_inside_transactional_fixtures ? 1 : 0
  raise LockMustBeOutermostTransaction unless connection.open_transactions == minimum_transaction_level

  objects.sort_by {|object| [object.class.name, object.send(object.class.primary_key)] }
  begin
    ActiveRecord::Base.locked_objects = nil
    transaction do
      begin
        objects.each(&:lock!)
        ActiveRecord::Base.locked_objects = objects
      rescue ActiveRecord::StatementInvalid => exception
        if exception.message =~ /Deadlock/
          raise RetryTransaction
        else
          raise
        end
      end

      yield
    end
  rescue RetryTransaction
    retry
  ensure
    ActiveRecord::Base.locked_objects = nil
  end
end