[CDBI] Re: Apps using Class::DBI

Bill Moseley moseley at hank.org
Wed Mar 29 23:28:27 BST 2006


On Wed, Mar 29, 2006 at 02:11:52PM -0500, Perrin Harkins wrote:
> The stuff on that wiki page is unnecessary.  I wouldn't touch
> do_transaction() with a 10 foot pole.  All you actually need is
> My::Class->dbi_commit().

Which part is unnecessary?

> These days I have started keeping AutoCommit on and turning it off for
> blocks where I want a transaction with local $dbh->{AutoCommit}, but
> that's all DBI-level stuff.  Class::DBI doesn't interfere with it.

Do you need to even change AutoCommit?  I just call $dbh->begin_work.
(Although John Siracusa currently is working out a problem with
rollback's failing with DBD:Pg and this method, IIRC).

One thing DBIC does is handle nested transactions.  It's rare that I
have nested transactions, but I had a need a week or so ago.  So, I
just added that to my own transaction code (by using the examples from
DBIC).  This doesn't seem that complex.  The do_begin, do_rollback,
and do_commit methods just checks a nested level to handle the nested
transactions.

You still see stuff that's not necessary?


sub do_transaction {

    my( $class, $code, @args ) = @_;

    $class->_invalid_object_method('do_transaction()') if ref $class;

    my @return_values = ();

    $class->do_begin;


    my $wa = wantarray;  # because wantarray is undefined inside the eval.

    eval {
        @return_values = $wa ? $code->(@args) : scalar $code->(@args);
        $class->do_commit;
    };

    return wantarray ? @return_values : $return_values[0]
        unless $@;




    my $error = $@;  # save due to eval for rollback

    # CDBI to reload the object
    $class->clear_object_index;

    eval{ $class->do_rollback; };

    $class->_croak("Transaction aborted: $error; Rollback failed: $@")
        if $@;

    $class->_croak("Transaction aborted (rollback successful): $error");

}





-- 
Bill Moseley
moseley at hank.org





More information about the ClassDBI mailing list