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



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

def method_missing(meth, *args, &block)
  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

#improvise(*args, &block) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/transactor/transaction.rb', line 43

def improvise(*args, &block)
  performance = Improv.new(*args)
  performances << performance
  performance.perform(&block)
  performance
rescue => e
  raise PerformanceBombed.new(e, performance)
end

#in_transaction(&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(&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

#last_performanceObject



80
81
82
# File 'lib/transactor/transaction.rb', line 80

def last_performance
  performances.last
end

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



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

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

#respond_to_missing?(meth, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/transactor/transaction.rb', line 94

def respond_to_missing?(meth, include_private=false)
  true # *shrug* we try to perform just about anything
end

#rollbackObject



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/transactor/transaction.rb', line 52

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_last_performance?Boolean

Returns:

  • (Boolean)


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

def rollback_last_performance?
  # only rollback the last performance if it didn't bomb OR if
  # it did and is configured to rollback on failure
  !last_performance.failed? || (last_performance.failed? && last_performance.rollback_on_failure?)
end

#rollback_performancesObject



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/transactor/transaction.rb', line 66

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

#transaction(&block) ⇒ Object



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

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

#transaction!(&block) ⇒ Object



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

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