Revision 0ade6272
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
SL/DB.pm | ||
---|---|---|
129 | 129 |
sub with_transaction { |
130 | 130 |
my ($self, $code, @args) = @_; |
131 | 131 |
|
132 |
return $self->in_transaction ? $code->(@args) : $self->do_transaction(sub { $code->(@args) }); |
|
132 |
return $code->(@args) if $self->in_transaction; |
|
133 |
if (wantarray) { |
|
134 |
my @result; |
|
135 |
return $self->do_transaction(sub { @result = $code->(@args) }) ? @result : (); |
|
136 |
|
|
137 |
} else { |
|
138 |
my $result; |
|
139 |
return $self->do_transaction(sub { $result = $code->(@args) }) ? $result : undef; |
|
140 |
} |
|
133 | 141 |
} |
134 | 142 |
|
135 | 143 |
1; |
... | ... | |
162 | 170 |
|
163 | 171 |
=item C<with_transaction $code_ref, @args> |
164 | 172 |
|
165 |
Executes C<$code_ref> within a transaction, starting one if none is |
|
166 |
currently active. This is just a shortcut for the following code: |
|
167 |
|
|
168 |
# Verbose code in caller (an RDBO instance): |
|
169 |
my $worker = sub { |
|
170 |
# do stuff with $self |
|
171 |
}; |
|
172 |
return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker); |
|
173 |
|
|
174 |
Now the version using C<with_transaction>: |
|
173 |
Executes C<$code_ref> with parameters C<@args> within a transaction, |
|
174 |
starting one if none is currently active. Example: |
|
175 | 175 |
|
176 | 176 |
return $self->db->with_transaction(sub { |
177 | 177 |
# do stuff with $self |
178 | 178 |
}); |
179 | 179 |
|
180 |
One big difference to L<Rose::DB/do_transaction> is the return code |
|
181 |
handling. If a transaction is already active then C<with_transcation> |
|
182 |
simply returns the result of calling C<$code_ref> as-is. |
|
183 |
|
|
184 |
Otherwise the return value depends on the result of the underlying |
|
185 |
transaction. If the transaction fails then C<undef> is returned in |
|
186 |
scalar context and an empty list in list context. If the transaction |
|
187 |
succeeds then the return value of C<$code_ref> is returned preserving |
|
188 |
context. |
|
189 |
|
|
190 |
So if you want to differentiate between "transaction failed" and |
|
191 |
"succeeded" then your C<$code_ref> should never return C<undef> |
|
192 |
itself. |
|
193 |
|
|
180 | 194 |
=back |
181 | 195 |
|
182 | 196 |
=head1 BUGS |
Auch abrufbar als: Unified diff
SL::DB::with_transaction: Rückgabewert konsistenter gemacht
Vorher gibt es mal den Rückgabewert von $code_ref, mal den von
Rose::DB::do_transaction. Nun ist es immer der von $code_ref, sofern
alles OK, und undef/() andernfalls -- inklusive Berücksichtigung des
Aufrufkontextes.