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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rose-db-object