Nice idea. I don't like the global $T though. Not only you have to do

our $T = $object; transaction {...}
but it also means that there may only be one object in the transaction. It would be much nicer if you could pass the object(s) to the transaction() directly. Like
transaction [$dbh1, $dbh2] => code{...}; # or transaction ($dbh1, $dbh2) => code{...};
Here's the modified version that allows both:
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 transactio +n!"; $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 rolle +d back"; } sub code (&) {return $_[0]} 1;
As you can note it tries to handle nesting transactions as well. The handling is like this: the ->commit for inner transactions is postponed to the successfull end of the outermost one, the rollback of a transaction only rollbacks that transaction and the transactions nested within it, but does not affect the outer transactions. Not sure this exactly matches the way rollback is handled in databases, but this at least makes sense.

Another small fix is that the "commit not safe after errors, transaction rolled back" message should be croak()ed, not die()d.

Jenda
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
   -- Rick Osborne

Edit by castaway: Closed small tag in signature


In reply to Re: RFC: Transactions.pm by Jenda
in thread RFC: Transactions.pm by Juerd

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.