eval {
local $dbh->{AutoCommit} = 0;
};
$self->{_can_do_transactions} = $@ ? 0 : 1;
####
$self->{_can_do_transactions} = eval {
local $dbh->{AutoCommit} = 0;
1
};
####
$self->{_can_do_transactions} = eval {
$dbh->begin_work();
$dbh->rollback()
};
####
my $in_trans = eval { $dbh->begin_work() };
if (!eval {
code_that_touches_db();
$dbh->commit() if $in_trans;
1
}) {
my $msg = $@;
eval { $dbh->rollback() } if $in_trans;
die $msg;
}
####
use Sub::ScopeFinalizer qw( scope_finalizer );
{
my $in_trans = eval { $dbh->begin_work() };
my $pending_rollback = scope_finalizer {
local $@;
eval { $dbh->rollback() } if $in_trans;
};
code_that_touches_db();
$pending_rollback->disable();
$dbh->commit() if $in_trans;
}
####
BEGIN {
package TransactionMaybe;
sub begin {
my ($class, $dbh) = @_;
my $in_trans = eval { $dbh->begin_work() };
return bless([$dbh, $in_trans], $class);
}
sub commit {
my ($self) = @_;
my $dbh = $self->[0];
our $in_trans; local *in_trans = \($self->[1]);
$dbh->commit() if $in_trans;
$in_trans = 0;
}
sub DESTROY {
my ($dbh, $in_trans) = @$self;
local $@;
eval { $dbh->rollback() } if $in_trans;
}
$INC{'TransactionMaybe.pm'} = 1;
}
{
my $transaction = TransactionMaybe->begin($dbh);
code_that_touches_db();
$transaction->commit();
}