On Oct 4, 2009, at 10:17 AM, Bill Moseley wrote:
This looks nice. Thanks. I don't use Apache::DBI, but this will be
good
for general connection and transaction support. I simply use
connect_cached
now with { privite_pid = $$ } but that doesn't allow me to set
InactiveDestroy (although I'm not using $dbh in Apache parent or
forking
children so has not been an issue).
Yeah, in that case, unless you want the transaction management or the
saving of the overhead of ping(), as long as you're not doing anything
in the parent process, I think what you've got is just fine. Very
simple.
I'm not quite sure how to handle the pings. I also don't like the
idea of a
ping every time a $dbh is needed. But, I wonder about re-issuing the
query.
Yes, you only want to do this if re-executing the code reference has
no side-effects.
If a do() throws an exception and then the connection is tested and
fails
the ping are you sure that the query didn't complete? My concern, of
course, is running the query successfully twice.
I stole this code from DBIx::Class, which as you likely know, is
pretty widely used. This was their approach, and I think it works well
for them. But even better is to use txn_do() instead, as it should
avoid the possibility of executing the query twice.
At one time I considered inspecting the error message and trying to
determine if it came from the database so that I knew the query
failed, and
then reconnect and rerun the query, otherwise just die.
Obviously, you can't reissue the query if in a transaction -- and I
see you
check for this.
Yep.
Checking the ping before returning $dbh isn't fool proof either. The
connection could always die between the ping and then when $dbh is
used.
Yet this is how the vast majority of database caching approaches work,
including Apache::DBI and connect_cached(). I don't think that's worth
worrying about, frankly.
Is the history of the ping to catch connections that have been
inactive for
a long period and perhaps timed out? I've thought about only
issuing the
ping if the $dbh hasn't been fetched in some amount of time (say a few
minutes) to effectively disable the pings when the site is busy (which
should be most of the time).
I think that would be more complicated; you'd have to do more record-
keeping. And then what do you do when you don't check it but a
reconnect would allow you to continue?
But, if you use txn_do() for all transactions then is there any need
for the
cleanup handler rollback?
No.
I also see in your disconnect method that you manually issue a
rollback,
call disconnect and then undefine $dbh. Doesn't DBI do that
automatically
when $dbh is DESTROYed?
Probably, unless InactiveDestroy is set. That's more code I borrowed
from DBIx::Class.
Best,
David