our $T = $object;
transaction {...}
####
transaction [$dbh1, $dbh2] => code{...};
# or
transaction ($dbh1, $dbh2) => code{...};
##
##
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 transaction!";
$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 rolled back";
}
sub code (&) {return $_[0]}
1;