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; }