I just read the POD for Apache::DBI, and then rewrote it.
Hope no-one is offended, that no meaning is lost, and that
the revision is worth looking at and perhaps including on CPAN.
Cheers
lee (now offlist)
=head1 NAME
Apache::DBI - Initiate a persistent database connection
=head1 SYNOPSIS
# Configuration in httpd.conf or startup.pl:
# This must come before all modules which use DBI,
# but after Apache::Status
PerlModule Apache::DBI
# No need to change anything in your scripts
# - the use of this module is absolutely transparent!
=head1 PREREQUISITES
Note that this module needs mod_perl-1.08 or higher, apache_1.3.0 or higher
and that mod_perl needs to be configured with the appropriate call-back hooks:
PERL_CHILD_INIT=1
PERL_STACKED_HANDLERS=1
=head1 DESCRIPTION
This module impliments persistent database connections for mod_perl,
through Perl's DBI. For supported DBI drivers see L<http://dbi.perl.org/>.
=head1 HOW IT WORKS
When the standard DBI.pm module is loaded after Apache::DBI, and the
environment variable C<GATEWAY_INTERFACE> starts with C>CGI-Perl>,
every database C<connect>ion request is passed to C<Apache::DBI>.
C<Apache::DBI> returns a database handle from a previous C<connect>ion
request if it is valid (using the C<ping> method), and if the parameters
defining the connection are exactly the same - including all the C<connect>
attributes.
If no appropriate database handle exists, or if the C<ping> method fails,
a new connection is established and the handle is stored for later re-use.
As C<Apache::DBI> overloads the C<disconnect> method of C<DBI.pm>, there
is no need to remove them from your code.
=head1 CAVEATS
=head2 THE PROBLEMS OF PER-PROCESS CONNECTIONS
C<Apache::DBI> still has one limitation: it keeps database connections
persistent on a I<per process> basis, with no sharing of database handles
between Apache processes, due to the distinct name-space of every process.
Neither is not possible to create a database handle upon the start-up of
the httpd,
and then to use this to handle every subsequent server, as this would cause
a clash
when the handle is used by two processes at once.
So take care when and where you use this module: there are scenarios where
the use of
C<Apache::DBI> is not encourage. Think about a heavy loaded Web-site where
every
user connects to the database with a unique user ID: every server process
would create
many database handles, each of which would spawn a separate process. In a short
time the web server would be flooded to death.
=head2 TIMEOUTS
Some databases disconnect their clients after a certain period of inactivity.
To detect this, C<Apache::DBI> attempts to validate the database handle using
the L<C<DBI::ping> method|DBI/ping>. Because this method returns true by
default,
any driver that does not implement the C<ping> method will not allow us to
test the validity of our handle.
There are several work-arounds: deactivate use of the ping method (see
L</CONFIGURATION>),
replace the C<ping> call with command you DB driver does support, or
impliment a
C<ping> method something like this:
{
package DBD::xxx::db; # ====== YOUR DATABASE ======
use strict;
sub ping {
my($dbh) = @_;
my $ret = 0;
eval {
local $SIG{__DIE__} = sub { return 0 };
local $SIG{__WARN__} = sub { return 0 };
# adapt the select statement to your database:
$ret = $dbh->do('select 1');
};
return $@? 0:$ret;
}
}
=head1 TRANSACTIONS
A standard DBI script will automatically perform a rollback
whenever the script exits. In the case of persistent database connections,
the database handle will not be destroyed and hence no automatic rollback
occurs.
At first glance it does seem possible to handle a transaction over multiple
requests, but this should be avoided, as different requests are handled by
different processes, and one process cannot know the state of a transaction
which initiated by another server.
In general, it is good practice to perform an explicit commit or rollback at
the end of every script. In order to avoid inconsistencies in the database
in case
C<AutoCommit> is off and the script finishes without an explicit rollback,
C<Apache::DBI> uses a C<PerlCleanupHandler> to issue a rollback at the
end of every request. Note, that this C<CleanupHandler> will only be used if
the initial data_source sets C<AutoCommit=0>. It will B<not> be used if
C<AutoCommit>
is turned off after the C<connect> request has been performed.
=head1 Apache::Status COMPATABILITY
C<Apache::DBI> includes a menu item plug-in for
L<Apache::Status|Apache::Status>,
which lists extant database connections. This should be considered
incomplete because of
the limitations explained above: it shows the current database connections
for just one specific server, that which happens to serve the current request.
Other servers might have other database connections.
Note that to use this feature, the C<Apache::Status> module has to be loaded
B<before> the C<Apache::DBI> module!
See also L</CONFIGURATION>.
=head1 CONFIGURATION
=over 4
The module should be loaded upon startup of the Apache daemon.
Add the following line to your C<httpd.conf> or C<startup.pl>:
erlModule Apache::DBI
(For more information, see L<the "PreLoad Perl Modules At Server Start-up"
item in "Performance, Benchmarks" section of "The mod_perl
Guide"|performance.html#Preload_Perl_Modules_at_Server_S>.)
=item MODULE-LOADING ORDER
It is important to load this module before any other modules using DBI
- and after C<Apache::Status> if you wish to make use of the C<Apache::Status>
menu plug-in (see L<Apache::Status COMPATABILITY>). For an example of
the configuration order when used with C<Apache::Status>, see F<eg/startup.pl>
enclosed with this distribution.
A common use of C<Apache::DBI> is to load the module in a startup file via
C<the PerlRequire> directive, as illustrated in the F<eg/startup.pl> enclosed
with this distribution.
=item SERVER-SPECIFIC CONFIGURATION
There are two configurations which are server-specific and which can be done
upon server startup:
Apache::DBI->connect_on_init( $data_source, $username, $auth, \%attr)
This can be used as a simple way to have apache servers establish connections
on process startup.
Apache::DBI->setPingTimeOut($data_source, $timeout)
This configures the use of the C<ping> method to validate a connection
(see L<"CAVEATS/TIMEOUTS">).
Setting the timeout to C<0> will always validate the database connection
using the C<ping> method (default). Setting the timeout to less than C<0>
will de-activate the validation of the database handle, useful for
drivers which do not implement the C<ping> method.
Setting the timeout to greater than C<0> will c<ping> the
database only if the last access was more than "timeout" seconds before.
=item DEBUGGING
To enable debugging, set C<$Apache::DBI::DEBUG> either in your F<startup.pl>,
or in your script. Setting the variable to C<1> reports just new connections.
Setting the variable to C<2> enables full debugging output.
=back
=head1 SEE ALSO
L<Apache>, L<mod_perl>, L<DBI>.
=head1 AUTHORS
=over 4
=item *
Apache::DBI by Edmund Mergl (now supported and maintained by
the modperl mailinglist, see the mod_perl documentation for
instructions on how to subscribe).
=item *
mod_perl by Doug MacEachern <[EMAIL PROTECTED]>
=item *
DBI by Tim Bunce <[EMAIL PROTECTED]>
=back
=head1 COPYRIGHT
The Apache::DBI module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut
Lee Goddard, BA(Hons), MSc(Sussex)
http://www.LeeGoddard.com/ since 1997.
Direcotr: Little Bits Ltd - Perl / Java / XML / HTML Contractors
Inc. in England #4006170; VAT #755-0139-42