Personally I don't use Apaceh::DBI, because I have a similar situation
to you. Here's how I do it, it may not be the best way but it's fairly
clean. It does make a separate DB connection in each apache process but
I think trying to share 1 DB connection between httpd's is probably
going to cost more than it gains.
You need 2 modules - one which is all the DB-related stuff, which works
a bit like DBI and can be used from cron scripts, CGI, whatever, and one
which is all the mod_perl handling.
In the DB-related module be sure to include a 'ping' method so your
mod_perl module can reconnect if the DB connection drops.
Create a new instance of the mod_perl handler module during startup and
refer to that for the handlers (code below).
This module would then cache DB connections and provide a method for
'create or fetch current DB connection'.
In my system, DB connections are virtual-server-specific (I get the DB
parameters from httpd.conf), so my 'get_db' method checks $r->dir_config
and finds or creates a DB connection with those parameters. If it finds
an existing one it calls 'ping' on it to ensure it's awake.
It looks a little something like this:
eg:
package MySystem::Database;
sub connect { ... $self->{_dbh}=DBI->connect_cached( etc ) } # even
more connection caching!
package MySystem::Apache2;
$MySystem::Apache2::Persistent=MySystem::Apache2->new();
sub new { .... }
sub handle_fixup ...
sub handle_response ...
sub get_db { if($self->{db}{server-specific-info}){ return that; }else{
MySystem::Database->new(....) }
and finally:
<VirtualServer ...>
PerlFixupHandler $MySystem::Apache2::Persistent->handle_fixup
PerlResponseHandler $MySystem::Apache2::Persistent->handle_response
</>
Tobias Kremer wrote:
Hey guys,
I'm wondering what's the best way to design a database-backed module
which works completely on its own as well as within mod_perl (mp1).
The module should make a database connection during object initialization
(new). This connection should then be used by all methods which want to
access the database (because I don't want to call "connect" before every
database query). That's easy under standalone conditions (connect within new,
store the dbh in $self->{_dbh} and use that in other methods).
Enter mod_perl. I'd like to create the object only ONCE during
server startup because it has to do some fairly heavy processing
with data from the database which I don't want to be done on every
request. The resulting state (some data structures) should then be saved
within the object's attributes for later quick and easy retrieval during
the request phase. Furthermore this object has methods which execute
more database queries (using the handle stored in $self->{_dbh}).
Now here's my concern: Because Apache::DBI will not cache the database
handle that was created during startup (some mechanisms luckily prevents
this), I fear that I might run into trouble having requests using the
object generated at server startup with a non-cached handle inside that is
shared among all apache children. I know that one should connect
in the request phase and let Apache::DBI do the magic, but in this case,
where the module is designed to be also used standalone, this is quite
tricky IMHO.
Hope you get the problem! Any ideas?
Thanx a lot!
Toby