Revision 2d43271a
Von Moritz Bunkus vor etwa 8 Jahren hinzugefügt
SL/DB.pm | ||
---|---|---|
159 | 159 |
=item C<with_transaction $code_ref, @args> |
160 | 160 |
|
161 | 161 |
Executes C<$code_ref> with parameters C<@args> within a transaction, |
162 |
starting one if none is currently active. Example: |
|
162 |
starting one only if none is currently active. Example:
|
|
163 | 163 |
|
164 | 164 |
return $self->db->with_transaction(sub { |
165 | 165 |
# do stuff with $self |
166 | 166 |
}); |
167 | 167 |
|
168 |
One big difference to L<Rose::DB/do_transaction> is the return code
|
|
169 |
handling. If a transaction is already active then C<with_transaction>
|
|
170 |
simply returns the result of calling C<$code_ref> as-is.
|
|
168 |
There are two big differences between C<with_transaction> and
|
|
169 |
L<Rose::DB/do_transaction>: the handling of an already-running
|
|
170 |
transaction and the handling of return values.
|
|
171 | 171 |
|
172 |
Otherwise the return value depends on the result of the underlying |
|
173 |
transaction. If the transaction fails then C<undef> is returned in |
|
174 |
scalar context and an empty list in list context. If the transaction |
|
175 |
succeeds then the return value of C<$code_ref> is returned preserving |
|
172 |
The first difference revolves around when a transaction is started and |
|
173 |
committed/rolled back. Rose's C<do_transaction> will always start one, |
|
174 |
then execute the code reference and commit afterwards (or roll back if |
|
175 |
an exception occurs). |
|
176 |
|
|
177 |
This prevents the caller from combining several pieces of code using |
|
178 |
C<do_transaction> reliably as results committed by an inner |
|
179 |
transaction will be permanent even if the outer transaction is rolled |
|
180 |
back. |
|
181 |
|
|
182 |
Therefore our C<with_transaction> works differently: it will only |
|
183 |
start a transaction if no transaction is currently active on the |
|
184 |
database connection. |
|
185 |
|
|
186 |
The second big difference to L<Rose::DB/do_transaction> is the |
|
187 |
handling of returned values. Basically our C<with_transaction> will |
|
188 |
return the values that the code reference C<$code_ref> returns (or |
|
189 |
C<undef> if the transaction was rolled back). Rose's C<do_transaction> |
|
190 |
on the other hand will only return a value signaling the transaction's |
|
191 |
status. |
|
192 |
|
|
193 |
In more detail: |
|
194 |
|
|
195 |
=over 2 |
|
196 |
|
|
197 |
=item * If a transaction is already active then C<with_transaction> |
|
198 |
will simply return the result of calling C<$code_ref> as-is preserving |
|
176 | 199 |
context. |
177 | 200 |
|
201 |
=item * If no transaction is started then C<$code_ref> will be wrapped |
|
202 |
in one. C<with_transaction>'s return value depends on the result of |
|
203 |
that transaction. If the it succeeds then the return value of |
|
204 |
C<$code_ref> will be returned preserving context. Otherwise C<undef> |
|
205 |
will be returned in scalar context and an empty list in list context. |
|
206 |
|
|
207 |
=back |
|
208 |
|
|
178 | 209 |
So if you want to differentiate between "transaction failed" and |
179 | 210 |
"succeeded" then your C<$code_ref> should never return C<undef> |
180 | 211 |
itself. |
Auch abrufbar als: Unified diff
SL::DB::with_transaction: bessere Doku zu den zwei Hauptunterschieden