[Dbix-class] transaction depth not reset in 0.08003

Brandon Black blblack at gmail.com
Wed Jul 18 22:09:14 GMT 2007


On 7/18/07, Richard Jolly <richardjolly at mac.com> wrote:
> On 18 Jul 2007, at 20:26, Brandon Black wrote:
>
> > Well, I've tracked this down a little bit further now.  I had poorly
> > assumed $dbh->{AutoCommit} would statically remain at whatever value
> > it was set to (or defaulted to) at DBI->connect time.  As it turns
> > out, $dbh->begin_work turns off the $dbh->{AutoCommit} value, which is
> > what's causing the confusion.
>
> We noticed this recently as well. Probably should have provided more
> hints in my original mail :(
>
> from DBI.pm:
>
>      sub begin_work {
>         my $dbh = shift;
>         return $dbh->set_err(1, "Already in a transaction")
>                 unless $dbh->FETCH('AutoCommit');
>         $dbh->STORE('AutoCommit', 0); # will croak if driver doesn't support it
>         $dbh->STORE('BegunWork',  1); # trigger post commit/rollback action
>         return 1;
>      }
>
> I'm wondering why DBI turns off autocommit rather than issuing a BEGIN
> WORK statement - but I guess that's for the DBI list. It appears to be
> so as to provide consistent behaviour/interface at the DBI level. We
> were thrown off for a while because the
> DBIx::Class::Storage::Statistics logging shows a 'BEGIN WORK'. Both DBI
> and D::C::S::S document the behaivour, but it is just counter-intuitive
> enough that it's easy to overlook.
>
> Thanks for the speedy response,
>

I've patched trunk now with what I had plus a few more little tidbits
(mostly to the tests themselves), I think this clears up the basic
issues we're having.  I'm still not fully confident that rollbacks
work right in nested transactions in all cases.

Certainly the "NESTED_ROLLBACK_EXCEPTION" exception isn't being thrown
when it used to be, and there were never any tests for that anyways.
I'm not really confident that I even understand the point of that
special exception, or fathom what the most correct behavior is in a
failed nested (fakely nested) transaction.  The way I've got it
running right now, in the case of txn_do, "inner" transactions are
completely fake, and any exception will propagate normally to the
outermost txn_do.  Obviously in the case of people manually using
txn_begin, it's up to what they're doing with their eval constructs.

Does anyone remember exactly what the original design of nested
txn_begin/txn_do + NESTED_ROLLBACK_EXCEPTION was supposed to work
like?  Without tests it's hard to say.

Josef's branch for mysql nested transactions using savepoints is quite
out of date, but when I next get back to this, I'll look at his diffs
and see if we can't get nesting nailed down for all cases (fake
nesting as a default, and savepoints on DBs that support it).
Savepoints appear to support arbitrary nesting on Pg and MySQL.

-- Brandon



More information about the Dbix-class mailing list