Nice idea. I don't like the global $T though. Not only you have to do
but it also means that there may only be one object in the transaction. It would be much nicer if you could pass the object(s) to the transaction() directly. Likeour $T = $object; transaction {...}
Here's the modified version that allows both:transaction [$dbh1, $dbh2] => code{...}; # or transaction ($dbh1, $dbh2) => code{...};
As you can note it tries to handle nesting transactions as well. The handling is like this: the ->commit for inner transactions is postponed to the successfull end of the outermost one, the rollback of a transaction only rollbacks that transaction and the transactions nested within it, but does not affect the outer transactions. Not sure this exactly matches the way rollback is handled in databases, but this at least makes sense.package Transactions; use strict; use Carp qw(croak); use Exporter::Tidy default => [ qw(transaction commit rollback code) ] +; our $VERSION = '0.04j'; my @trans; my $trancount = 0; sub commit () { my $vars = pop @trans or croak "commit called outside transaction! +"; $trancount--; if ($trancount == 0) { # the outermost transaction $_->commit for reverse @$vars; } else { push @{$trans[-1]}, @$vars; } local $^W; # "exiting sub via last" last __TRANSACTION; } sub rollback () { my $vars = pop @trans or croak "rollback called outside transactio +n!"; $trancount--; $_->rollback for reverse @$vars; local $^W; # "exiting sub via last" last __TRANSACTION; } sub transaction ($$;@) { my $block = pop @_; my @vars = @_; @vars = @{$vars[0]} if (@vars == 1 and ref($vars[0]) eq 'ARRAY'); push @trans, \@vars; $trancount++; __TRANSACTION: { eval { $_->begin_work for @vars; $block->(); }; $@ ? rollback : commit; } $@ and croak $@ . "commit not safe after errors, transaction rolle +d back"; } sub code (&) {return $_[0]} 1;
Another small fix is that the "commit not safe after errors, transaction rolled back" message should be croak()ed, not die()d.
Jenda
Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live.
-- Rick Osborne
Edit by castaway: Closed small tag in signature
In reply to Re: RFC: Transactions.pm
by Jenda
in thread RFC: Transactions.pm
by Juerd
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |