torquebox-transactions 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,11 +30,10 @@ module TorqueBox
30
30
  # The default module mixed into the Manager. Adapters for various
31
31
  # resources are expected to override these methods as appropriate
32
32
  # for their library. See ActiveRecordAdapters::Transaction, for
33
- # example. These are the methods invoked by Manager#with_tx()
33
+ # example.
34
34
  module Transaction
35
35
 
36
36
  def prepare
37
- @transactions.push( @tm.suspend ) if active?
38
37
  @tm.begin
39
38
  end
40
39
 
@@ -46,15 +45,6 @@ module TorqueBox
46
45
  @tm.rollback
47
46
  end
48
47
 
49
- def cleanup
50
- @tm.suspend
51
- if @transactions.last
52
- @tm.resume( @transactions.pop )
53
- else
54
- Thread.current[:torquebox_transaction] = nil
55
- end
56
- end
57
-
58
48
  def error( exception )
59
49
  puts "Transaction rollback: #{exception}"
60
50
  rollback
@@ -88,37 +78,122 @@ module TorqueBox
88
78
  end
89
79
  end
90
80
 
91
- # Where we either begin a new transaction (with_tx) or simply
92
- # yield as part of the current transaction.
93
- def run(*args, &block)
94
- return yield unless @tm
95
- opts = args.last.is_a?(Hash) ? args.pop : {}
96
- if active? && !opts[:requires_new]
97
- enlist(*args)
98
- yield
99
- else
100
- with_tx do
101
- enlist(*args)
102
- block.call
103
- end
104
- end
105
- end
106
-
107
81
  # Is there an active transaction?
108
82
  def active?
109
83
  @tm.transaction != nil
110
84
  end
111
85
 
112
- # The heart of the matter
113
- def with_tx
86
+ # Begin a transaction, yield, commit or rollback on error.
87
+ def start
114
88
  prepare
115
89
  result = yield
116
90
  commit
117
91
  result
118
92
  rescue Exception => e
119
93
  error(e)
94
+ end
95
+
96
+ # Suspend current transaction, yield, and resume
97
+ def suspend
98
+ @transactions.push( @tm.suspend )
99
+ yield
100
+ ensure
101
+ @tm.resume( @transactions.pop )
102
+ end
103
+
104
+ # JEE Required
105
+ def required &block
106
+ if active?
107
+ yield
108
+ else
109
+ start &block
110
+ end
111
+ end
112
+
113
+ # JEE RequiresNew
114
+ def requires_new &block
115
+ if active?
116
+ suspend do
117
+ start &block
118
+ end
119
+ else
120
+ start &block
121
+ end
122
+ end
123
+
124
+ # JEE NotSupported
125
+ def not_supported &block
126
+ if active?
127
+ suspend &block
128
+ else
129
+ yield
130
+ end
131
+ end
132
+
133
+ # JEE Supports
134
+ def supports
135
+ yield
136
+ end
137
+
138
+ # JEE Mandatory
139
+ def mandatory
140
+ if active?
141
+ yield
142
+ else
143
+ raise "No active transaction"
144
+ end
145
+ end
146
+
147
+ # JEE Never
148
+ def never
149
+ if active?
150
+ raise "Active transaction detected"
151
+ else
152
+ yield
153
+ end
154
+ end
155
+
156
+ # Returns a 2-element tuple [resources, method] where method is
157
+ # a symbol corresponding to one of the JEE tx attribute methods
158
+ # above. All but the last argument should be XA resources to be
159
+ # enlisted in the transaction. The last argument passed is
160
+ # expected to be either a symbol referring to one of the JEE
161
+ # methods or a Hash in which the method symbol is associated
162
+ # with the :scope key. If omitted, defaults to :required.
163
+ #
164
+ # For backwards compatibility the hash may also contain a
165
+ # :requires_new key which, if true, will result in the
166
+ # :requires_new method symbol being returned.
167
+ #
168
+ # :none may be used as an alias for :not_supported
169
+ #
170
+ # Whew!
171
+ def parse_args(*args)
172
+ resources, method = case args.last
173
+ when Symbol
174
+ last = args.pop
175
+ [args, last]
176
+ when Hash
177
+ hash = args.pop
178
+ last = hash[:scope] || (hash[:requires_new] ? :requires_new : :required)
179
+ [args, last]
180
+ else
181
+ [args, :required]
182
+ end
183
+ method = :not_supported if method == :none
184
+ [resources, method]
185
+ end
186
+
187
+ def run(*args, &block)
188
+ return yield unless @tm
189
+ resources, method = parse_args(*args)
190
+ fn = lambda do
191
+ enlist(*resources)
192
+ block.call
193
+ end
194
+ send(method, &fn)
120
195
  ensure
121
- cleanup
196
+ Thread.current[:torquebox_transaction] = nil if @transactions.empty?
122
197
  end
123
198
 
124
199
  end
@@ -0,0 +1,60 @@
1
+ require 'torquebox/transactions'
2
+
3
+ describe TorqueBox::Transactions do
4
+
5
+ describe "argument parsing" do
6
+
7
+ before(:each) do
8
+ @mgr = TorqueBox::Transactions::Manager.new
9
+ end
10
+
11
+ it "should parse resources followed by a symbol" do
12
+ resources, method = @mgr.parse_args(1, 2, 3, :requires_new)
13
+ resources.should == [1, 2, 3]
14
+ method.should == :requires_new
15
+ end
16
+
17
+ it "should parse only a symbol" do
18
+ resources, method = @mgr.parse_args(:requires_new)
19
+ resources.should == []
20
+ method.should == :requires_new
21
+ end
22
+
23
+ it "should parse no args, returning :required, by default" do
24
+ resources, method = @mgr.parse_args
25
+ resources.should == []
26
+ method.should == :required
27
+ end
28
+
29
+ it "should parse :none to :not_supported" do
30
+ resources, method = @mgr.parse_args(:none)
31
+ resources.should == []
32
+ method.should == :not_supported
33
+ end
34
+
35
+ it "should parse resources followed by a hash" do
36
+ resources, method = @mgr.parse_args(1, 2, 3, :requires_new => true)
37
+ resources.should == [1, 2, 3]
38
+ method.should == :requires_new
39
+ end
40
+
41
+ it "should parse only a hash" do
42
+ resources, method = @mgr.parse_args(:requires_new => true)
43
+ resources.should == []
44
+ method.should == :requires_new
45
+ end
46
+
47
+ it "should parse only a hash containing :scope key" do
48
+ resources, method = @mgr.parse_args(:scope => :mandatory)
49
+ resources.should == []
50
+ method.should == :mandatory
51
+ end
52
+
53
+ it "should parse only a hash, preferring :scope to :requires_new" do
54
+ resources, method = @mgr.parse_args(:scope => :required, :requires_new => true)
55
+ resources.should == []
56
+ method.should == :required
57
+ end
58
+
59
+ end
60
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: torquebox-transactions
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.1.0
5
+ version: 2.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - The TorqueBox Team
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-07-26 00:00:00 Z
13
+ date: 2012-08-27 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: torquebox-core
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - "="
22
22
  - !ruby/object:Gem::Version
23
- version: 2.1.0
23
+ version: 2.1.1
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
26
  - !ruby/object:Gem::Dependency
@@ -48,6 +48,7 @@ files:
48
48
  - lib/torquebox/active_record_adapters.rb
49
49
  - lib/torquebox/transactions.rb
50
50
  - lib/torquebox/transactions/ext/active_record/base.rb
51
+ - spec/transactions_spec.rb
51
52
  homepage: http://torquebox.org/
52
53
  licenses:
53
54
  - lgpl
@@ -75,5 +76,5 @@ rubygems_version: 1.8.24
75
76
  signing_key:
76
77
  specification_version: 3
77
78
  summary: TorqueBox Transactions Gem
78
- test_files: []
79
-
79
+ test_files:
80
+ - spec/transactions_spec.rb