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

Reply via email to