Incorporating feedback (thanks) and other ideas:

        sub perform_transaction {
!           my ($dbh, $attr, $coderef, @args) = @_;
            my $wantarray = wantarray;
            my $use_transaction = 1;
            my $orig_AutoCommit = $dbh->{AutoCommit};
            if ($orig_AutoCommit) {
                unless (eval { $dbh->{AutoCommit} = 0; 1 }) {
                    die unless $allow_non_transaction;
                    $use_transaction = 0;
                }
            }
+           local $dbh->{RaiseError} = 1;
            eval {
                @result = ($wantarray) ? $coderef->(@args) : scalar $coderef->(@args);
                $dbh->commit if $use_transaction;
+               $attr->{OnCommit}->() if $attr->{OnCommit}->();
            };
            if ($@) {
                local $@; protect original error
!               my $rv = eval { ($use_transaction) ? $dbh->rollback : 0 };
+               $attr->{OnRollback}->($rv) if $attr->{OnRollback};
            }
            die if $@; # propagate original error
            $dbh->{AutoCommit} = 1 if $orig_AutoCommit;
            return $result[0] unless $wantarray;
            return @result;
        }

But as I tinker with it I wonder if it's a solution chasing a problem.
Where, and how, and why, would it be used?

Anyone got any realistic examples?

Tim.

Reply via email to