Class: Transactor::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/transactor/transaction.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object



93
94
95
96
97
98
99
100
101
102
# File 'lib/transactor/transaction.rb', line 93

def method_missing(meth, *args, &block)
  if meth.to_s.match(/=\Z/)
    key = meth.to_s.gsub(/=/,'').to_sym
    return (@context[key] = args.first) if @context.key?(key)
  else
    return @context[meth] if @context.key?(meth)
  end

  perform meth, *args, &block
end

Instance Attribute Details

#performancesObject (readonly)

Returns the value of attribute performances.



3
4
5
# File 'lib/transactor/transaction.rb', line 3

def performances
  @performances
end

#resultObject (readonly)

Returns the value of attribute result.



3
4
5
# File 'lib/transactor/transaction.rb', line 3

def result
  @result
end

Instance Method Details

#clear_context!Object



89
90
91
# File 'lib/transactor/transaction.rb', line 89

def clear_context!
  @context = {}
end

#improvise(*args, &block) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/transactor/transaction.rb', line 44

def improvise(*args, &block)
  block ||= Proc.new {}
  args = performance_args(*args)
  performance = Improv::Performance.new(Improv::Actor, *args)
  performances << performance
  performance.perform(&block)
  performance
rescue PerformanceBombed => e
  raise e
rescue => e
  raise PerformanceBombed.new(e, performance)
end

#in_transaction(*args, &block) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/transactor/transaction.rb', line 5

def in_transaction(*args, &block)
  begin
    @result = instance_eval &block if block_given?
  rescue Exception => e # yes, we want to catch everything
    begin
      rollback
    rescue Exception => e # yes, here too
      raise RollbackFailed.new(e, self)
    end

    raise TransactionFailed.new(e, self)
  end
end

#perform(actor, *args, &block) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/transactor/transaction.rb', line 34

def perform(actor, *args, &block)
  args = performance_args(*args)
  performance = Performance.new(actor, *args)
  performances << performance
  performance.perform(&block)
  performance.result
rescue => e
  raise PerformanceBombed.new(e, performance)
end

#rollbackObject



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/transactor/transaction.rb', line 57

def rollback
  return true if performances.empty?

  if rollback_last_performance?
    rollback_performances
  else
    bombed = performances.pop
    rollback_performances
    performances << bombed
  end
  
  true
end

#rollback_performancesObject



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/transactor/transaction.rb', line 71

def rollback_performances
  performances.reverse.each do |performance|
    begin
      performance.rollback
    rescue RollbackNotImplemented => e
      # noop, rollback was not implemented
    rescue => e
      # there was an error rolling back the performance
      # do we halt the transaction rollback here? return the performances and allow manual rollbacks?
      raise RollbackBombed.new(e, performance)
    end
  end
end

#set_context!(*args) ⇒ Object



85
86
87
# File 'lib/transactor/transaction.rb', line 85

def set_context!(*args)
  @context = args.extract_options!.symbolize_keys
end

#transaction(*args, &block) ⇒ Object



28
29
30
31
32
# File 'lib/transactor/transaction.rb', line 28

def transaction(*args, &block)
  transaction!(*args, &block)
rescue => e
  false
end

#transaction!(*args, &block) ⇒ Object



19
20
21
22
23
24
25
26
# File 'lib/transactor/transaction.rb', line 19

def transaction!(*args, &block)
  if defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:transaction)
    ActiveRecord::Base.transaction { in_transaction *args, &block }
  else
    in_transaction *args, &block
  end
  self
end