in reply to RFC: Transactions.pm
I would suggest you work with die instead though - that will work with nested transactions and require fewer hoop jumps. You can then also easily add some more error checking:sub commit () { ($T || ${ caller() . '::T' })->commit; goto END_XACTION; } sub rollback () { ($T || ${ caller() . '::T' })->rollback; goto END_XACTION; } sub transaction (&) { my ($block) = @_; local $T = ${ caller() . '::T' } or croak "\$T not set"; local $@; eval { $T->begin_work; $block->(); }; $@ ? rollback : commit; END_XACTION: die $@ . "commit not safe after errors, transaction r +olled back" if $@; }
sub commit { require Carp; Carp::croak("Can't commit outside a transaction"); } sub rollback { require Carp; Carp::croak("Can't rollback outside a transaction"); } sub transaction (&) { my ($block) = @_; my $caller = caller(); local *{"${caller}::commit"} = sub { die "!COMMIT\n" }; local *{"${caller}::rollback"} = sub { die "!ROLLBACK\n" }; local $@; eval { $T->begin_work; $block->(); }; if(!$@ or $@ eq "!COMMIT\n") { ${"${caller}::T"}->commit; } elsif($@ eq "!ROLLBACK\n") { ${"${caller}::T"}->rollback; } else { ${"${caller}::T"}->rollback; require Carp; Carp::croak($@ . "commit not safe after errors, transaction ro +lled back"); } }
Makeshifts last the longest.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: RFC: Transactions.pm
by Juerd (Abbot) on Apr 28, 2003 at 12:16 UTC | |
by Aristotle (Chancellor) on Apr 28, 2003 at 12:21 UTC | |
by Juerd (Abbot) on Apr 28, 2003 at 14:58 UTC | |
by Aristotle (Chancellor) on Apr 28, 2003 at 18:37 UTC |