http://qs321.pair.com?node_id=253475

Update: working code now. I even tested it with a database to be sure, this time.

Update: third version, based mostly on crenz' and Aristotle's suggestions.

I dreamt about being able to simply use transaction { ... } to do what I mean (see SYNOPSIS below). It was quite easy to code. Please review the module before I upload it to CPAN.

The module does not have "DBIx" in its name, because in theory it can be used with any package that has begin_work, commit and rollback methods.

package Transactions; use Carp qw(croak); use Exporter::Tidy default => [ qw(transaction commit rollback) ]; our $VERSION = '0.03'; sub commit () { croak "Can't commit outside a transaction" } sub rollback () { croak "Can't rollback outside a transaction" } sub transaction ($&) { my ($object, $sub) = @_; local $^W; local *{ caller() . '::commit' } = sub () { die "COMMIT\n" }; local *{ caller() . '::rollback' } = sub () { die "ROLLBACK\n" }; local $@; eval { $object->begin_work; $sub->(); }; if ($@ eq "COMMIT\n") { $object->commit; } elsif ($@ eq "ROLLBACK\n") { $object->rollback; } elsif ($@) { die $@ . "commit not safe after errors, transaction rolled bac +k.\n"; } else { $object->commit; } } 1; __END__ =head1 NAME transactions - Easier DBI(-ish) transactions =head1 SYNOPSIS use Transactions; my $dbh = DBI->connect(...); transaction $dbh, sub { for (1..10) { my $sth = $dbh->prepare(...); $sth->execute() or rollback; } }; =head1 DESCRIPTION This module exports custom C<transaction>, C<commit> and C<rollback> functions to make using transactions easier. =head2 Functions =over 13 =item transaction $object, sub BLOCK Begins a transaction and evals BLOCK. Commits the transaction if the BLOCK does not die, rolls it back when it does. $object is the object that can() C<begin_transaction>, C<commit> and C<rollback>. =item commit To be used in C<transaction>'s BLOCK. Commits the transaction and ends the block (like C<last>). =item rollback To be used in C<transaction>'s BLOCK. Rolls the transaction back and ends the block (like C<last>). =back =head1 CAVEATS Do not nest transactions. Maybe it works, but I haven't tested that. The code block actually is a sub, so in it, C<return> ends only that code block, not any surrounding subroutine. =head1 LICENSE There is no license. This software was released into the public domain. Do with it what you want, but on your own risk. The author disclaims any responsibility. =head1 AUTHOR Juerd Waalboer <juerd@cpan.org> <http://juerd.nl/> =cut

Comments and patches are welcome! Thanks in advance.

Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }