On 17.08.2007 16:20 John Siracusa wrote: > On 8/15/07, Michael Lackhoff <[EMAIL PROTECTED]> wrote: >> my $db = My::DB->new(); >> >> $db->do_transaction( >> sub { >> my $o = My::Thing->new(); >> $o->foo(123); >> $o->bar(456); >> $o->save; >> die "Does it rollback?"; >> } >> ); >> >> This code does _not_ do a rollback. > > When running under Apache::DBI, this line issues a rollback: > > warn $o->db->dbh();
So, if I understand it right, there are really two problems: - no rollback when it should be (my do_transaction above) - a rollback when there should be none (your warn) > Apache::DBI::reset_startup_state() > And there you have it. The $dbh that belongs to the $db that you > called do_transaction() on has now been rolled back, and it's had its > AutoCommit attribute set back to what it was on connect (1 in your > case). I must admit that I don't really understand what is going wrong in reset_startup_state but even if I comment the call to reset_startup_state out in Apache::DBI (as suggested before) the above do_transaction code still doesn't roll back. So I cannot see how the detailed sequence you show, leading to reset_startup_state, does explain why my do_transaction doesn't roll back. > So, the question is, what do we do to fix this? Obviously, one work > around is to pass the same $db around to all objects. You can also > change your init_db() routine in your common base class to be this > instead: > > our $DB; > sub init_db { $DB ||= My::DB->new } Until the experts find a better solution I have done something very similar (only with a closure instead of the global variable). At an early stage of every request I reset $DB (don't know if this is really necessary) to be sure that transactions do not span requests. A Cleanup handler now does a rollback on this $DB. Looks good so far. > But really, I'd like to solve this somehow so the default way works as > well. It would be nice if I could ask Apache::DBI not to call > reset_startup_state(), perhaps by passing a special connect attribute: > > DBI->connect(..., { private_Apache_DBI_No_Reset => 1, ... }); As I said, at least in my code it doesn't make any difference. > Finally, I suppose I could change the default implementation of > init_db() to be more like this instead: > > sub init_db { $DB ||= Rose::DB->new } > > But that'd be quite a behavior change, and it'd have its own set of problems. What are the problems here? Since I adopted this for the time being it would be nice to know what I have to expect... Thanks for digging into it - Michael ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Rose-db-object mailing list Rose-db-object@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rose-db-object