torquebox-transactions 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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