From 0ade6272841acc5870970a0a0949f44baca54d8f Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 15 May 2013 12:02:06 +0200 Subject: [PATCH] =?utf8?q?SL::DB::with=5Ftransaction:=20R=C3=BCckgabewert?= =?utf8?q?=20konsistenter=20gemacht?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. --- SL/DB.pm | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/SL/DB.pm b/SL/DB.pm index 90e08c582..5a22c5da5 100644 --- a/SL/DB.pm +++ b/SL/DB.pm @@ -129,7 +129,15 @@ sub _flatten_settings { sub with_transaction { my ($self, $code, @args) = @_; - return $self->in_transaction ? $code->(@args) : $self->do_transaction(sub { $code->(@args) }); + return $code->(@args) if $self->in_transaction; + if (wantarray) { + my @result; + return $self->do_transaction(sub { @result = $code->(@args) }) ? @result : (); + + } else { + my $result; + return $self->do_transaction(sub { $result = $code->(@args) }) ? $result : undef; + } } 1; @@ -162,21 +170,27 @@ configuration. =item C -Executes C<$code_ref> within a transaction, starting one if none is -currently active. This is just a shortcut for the following code: - - # Verbose code in caller (an RDBO instance): - my $worker = sub { - # do stuff with $self - }; - return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker); - -Now the version using C: +Executes C<$code_ref> with parameters C<@args> within a transaction, +starting one if none is currently active. Example: return $self->db->with_transaction(sub { # do stuff with $self }); +One big difference to L is the return code +handling. If a transaction is already active then C +simply returns the result of calling C<$code_ref> as-is. + +Otherwise the return value depends on the result of the underlying +transaction. If the transaction fails then C is returned in +scalar context and an empty list in list context. If the transaction +succeeds then the return value of C<$code_ref> is returned preserving +context. + +So if you want to differentiate between "transaction failed" and +"succeeded" then your C<$code_ref> should never return C +itself. + =back =head1 BUGS -- 2.20.1