You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Ken Perl <ke...@gmail.com> on 2007/07/30 12:21:21 UTC

how to use Apache::DBI

I've configured  the Apache::DBI in httpd.conf like this,

PerlModule Apache::DBI

I didn't have  Apache::DBI->connect_on_init($data_source, $username,
$auth, \%attr) in startup.pl since we don't use startup.pl. and the
doc says to config it in httpd.conf is OK.

my question is I can not find any persistent connections for my CGI
script. any usage error here?

-- 
perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
")'

Re: how to use Apache::DBI

Posted by Arshavir Grigorian <gr...@gmail.com>.
connect_on_init() creates the database connection when the Apache
child process starts (vs when it serves the first request). This
ensures that the first request gets to use an existing connection vs
having to wait for a connection to be made.

Also to benefit from Apache::DBI functionality your script needs to be
running under modperl (via Apache2::Registry). Is it running under
modperl?



On 7/30/07, Ken Perl <ke...@gmail.com> wrote:
> I've configured  the Apache::DBI in httpd.conf like this,
>
> PerlModule Apache::DBI
>
> I didn't have  Apache::DBI->connect_on_init($data_source, $username,
> $auth, \%attr) in startup.pl since we don't use startup.pl. and the
> doc says to config it in httpd.conf is OK.
>
> my question is I can not find any persistent connections for my CGI
> script. any usage error here?
>
> --
> perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
> ")'
>

Re: how to use Apache::DBI

Posted by Perrin Harkins <pe...@elem.com>.
On 7/30/07, Ken Perl <ke...@gmail.com> wrote:
> my question is I can not find any persistent connections for my CGI
> script.

If you are running your scripts through ModPerl::Registry, all you
need to do is call DBI->connect normally and you will get persistent
connections.

- Perrin

Re: how to use Apache::DBI

Posted by Perrin Harkins <pe...@elem.com>.
On 7/30/07, Dodger <se...@aquest.com> wrote:
> You're being semantically picky with this guy, and innacurately so.
> An apache registry script *is* a CGI script. So is an ASP page, a PHP
> script, and any other interpreted way fo dealing with CGI input.

We tend to be generous with the use of the word "CGI" around here, but
technically, if it isn't using the CGI protocol as exemplified by
mod_cgi, it isn't CGI.  People often run PHP through CGI, but when
they use mod_php it's not CGI.  ASP is not able to run as CGI.

> CGI stands for 'Common Gateway Interface and describes the method of
> transferring information to a form to the server.

That's actually HTTP.  CGI defines how the server runs the program on
the server, by forking a program and passing things through ENV and
STDIN.  We don't do that in mod_perl, although we sometimes fake it so
that legacy code can still work.

> The guy also obviously most likely has mod_perl because he is using the
> PerlModule directive in his conf *and* because he's using a startup.pl file.

He may have it compiled in, but may not be running any of his scripts
through it, in which case Apache::DBI won't work for him.  The
questions Clinton asked are relevant to figuring out how to help him,
and I don't see any bad intentions there.

- Perrin

Re: how to use Apache::DBI

Posted by Dodger <se...@aquest.com>.
Clinton Gormley wrote:
> On Mon, 2007-07-30 at 18:21 +0800, Ken Perl wrote:
>   
>> I've configured  the Apache::DBI in httpd.conf like this,
>>
>> PerlModule Apache::DBI
>>
>> I didn't have  Apache::DBI->connect_on_init($data_source, $username,
>> $auth, \%attr) in startup.pl since we don't use startup.pl. and the
>> doc says to config it in httpd.conf is OK.
>>
>> my question is I can not find any persistent connections for my CGI
>> script. any usage error here?
>>     
>
> Persistent connections will not work for straight CGI scripts, because
> CGI is not persistent.
>
> For each CGI request, a new perl interpreter is loaded, your script is
> compiled, run, and the Perl process exits.
>
> mod_perl IS persistent, as are your CGI scripts run via
> ModPerl::Registry etc.
>
> You don't need connect_on_init to work, but you do need mod_perl
>
> Clint
>   
Mr Gormley,

You're being semantically picky with this guy, and innacurately so.
An apache registry script *is* a CGI script. So is an ASP page, a PHP 
script, and any other interpreted way fo dealing with CGI input.

CGI stands for 'Common Gateway Interface and describes the method of 
transferring information to a form to the server. A CGI
script is therefore a script designed to deal with CGI input, which 
means it doesn't matter if it's in Perl or not, and it doesn't matter if 
it's an Apache Registry script or a standalone non-mod_perl Perl script 
that's doing the work. All that matters is that it can read CGI input 
(or at least the subset that it's designed to deal with) and that it is 
interpreted at runtime (as mod_perl registry CGI scripts are).

The guy also obviously most likely has mod_perl because he is using the 
PerlModule directive in his conf *and* because he's using a startup.pl file.

-- 
Dodger

Re: how to use Apache::DBI

Posted by Ken Perl <ke...@gmail.com>.
ok, I'll try connect_cached too.

On 8/1/07, Perrin Harkins <pe...@elem.com> wrote:
> On 7/31/07, Clinton Gormley <cl...@traveljury.com> wrote:
> > What you could do instead is to use DBI's connect_cached method, which
> > provides similar functionality.  I actually use this instead of
> > Apache::DBI, even when running under mod_perl.
>
> I also use connect_cached in many cases.  Just be aware of what you're
> missing out on, because Apache::DBI does some extra things to protect
> you.
>
> Here are the main differences:
> - Apache::DBI doesn't require code changes.  connect_cached() does.
> - Apache::DBI will avoid caching a connection that you open during
> server startup, so that you don't accidentally try to use the same
> connection in multiple processes (due to forking).
> - Apache::DBI issues an automatic rollback at the end of every
> request, so that if your code dies while it has a transaction going,
> that will be freed before the next request.  (This is only if you open
> your handles with AutoCommit off though.)
>
> Hmm, maybe this should be in the Apache::DBI documentation.
>
> - Perrin
>


-- 
perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
")'

Re: how to use Apache::DBI

Posted by Perrin Harkins <pe...@elem.com>.
On 7/31/07, Clinton Gormley <cl...@traveljury.com> wrote:
> What you could do instead is to use DBI's connect_cached method, which
> provides similar functionality.  I actually use this instead of
> Apache::DBI, even when running under mod_perl.

I also use connect_cached in many cases.  Just be aware of what you're
missing out on, because Apache::DBI does some extra things to protect
you.

Here are the main differences:
- Apache::DBI doesn't require code changes.  connect_cached() does.
- Apache::DBI will avoid caching a connection that you open during
server startup, so that you don't accidentally try to use the same
connection in multiple processes (due to forking).
- Apache::DBI issues an automatic rollback at the end of every
request, so that if your code dies while it has a transaction going,
that will be freed before the next request.  (This is only if you open
your handles with AutoCommit off though.)

Hmm, maybe this should be in the Apache::DBI documentation.

- Perrin

Re: how to use Apache::DBI

Posted by Clinton Gormley <cl...@traveljury.com>.
On Tue, 2007-07-31 at 14:36 +0800, Ken Perl wrote:
> OK, got it. Is it possible to use the same db connections in one
> request? if yes, could you please show me how to implement this if a
> cgi script calls many times other perl modules which requests db
> connections to work.
> 


Yes it is, although I'm not sure about using it with straight CGI (ie
not via ModPerl::Registry/PerlRun etc).

The opening lines of Apache::DBI contain this:

---------------------------------------
use constant MP2 => (exists $ENV{MOD_PERL_API_VERSION} &&
                     $ENV{MOD_PERL_API_VERSION} == 2) ? 1 : 0;
BEGIN {
    if (MP2) {
        require mod_perl2;
        require Apache2::Module;
        require Apache2::ServerUtil;
    }
    elsif (defined $modperl::VERSION && $modperl::VERSION > 1 &&
             $modperl::VERSION < 1.99) {
        require Apache;
    }
}
---------------------------------------

So I would assume that if you use Apache::DBI in a CGI script, it's not
going to have the MOD_PERL* environment variables set, and so it will
assume mod_perl version 1, and require Apache.  

However, I see no reason to load the Apache.pm module in your case - you
don't need it.

What you could do instead is to use DBI's connect_cached method, which
provides similar functionality.  I actually use this instead of
Apache::DBI, even when running under mod_perl.

In either case, the way to reuse connections is to ensure that your
connect call is exactly the same.  Even changing the order of parameters
will force Apache::DBI / connect_cached to generate a new connection.

Clint


Re: how to use Apache::DBI

Posted by Ken Perl <ke...@gmail.com>.
OK, got it. Is it possible to use the same db connections in one
request? if yes, could you please show me how to implement this if a
cgi script calls many times other perl modules which requests db
connections to work.

On 7/31/07, Perrin Harkins <pe...@elem.com> wrote:
> On 7/30/07, Ken Perl <ke...@gmail.com> wrote:
> > I didn't run it under ModPerl::Registry
>
> Did you run it under some other mod_perl module, like
> ModPerl::PerlRun?  If it's a CGI script, and you aren't running it
> through something like this, then you aren't running it through
> mod_perl and you won't be able to use persistent connections.
>
> > Could I just run use the previous connections via DBI->connect_cache
> > instead of the Apache::DBI in one single cgi script
>
> Not if you aren't running it through mod_perl.  CGI scripts exit after
> each request, so they can't do persistent connections.
>
> - Perrin
>


-- 
perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
")'

Re: how to use Apache::DBI

Posted by Perrin Harkins <pe...@elem.com>.
On 7/30/07, Ken Perl <ke...@gmail.com> wrote:
> I didn't run it under ModPerl::Registry

Did you run it under some other mod_perl module, like
ModPerl::PerlRun?  If it's a CGI script, and you aren't running it
through something like this, then you aren't running it through
mod_perl and you won't be able to use persistent connections.

> Could I just run use the previous connections via DBI->connect_cache
> instead of the Apache::DBI in one single cgi script

Not if you aren't running it through mod_perl.  CGI scripts exit after
each request, so they can't do persistent connections.

- Perrin

Re: how to use Apache::DBI

Posted by Ken Perl <ke...@gmail.com>.
it is really good gotchas and should be included to the
ModPerl::Registry document. thanks a lot.

On 7/31/07, Clinton Gormley <cl...@traveljury.com> wrote:
> On Tue, 2007-07-31 at 10:09 +0800, Ken Perl wrote:
> > I didn't run it under ModPerl::Registry, is there any risk to use the
> > module? maybe I have to run lots of testing to the existing scripts.
> >
>
>
> There is a risk to using this module, but also a significant benefit:
> speed.
>
> The risks come from:
>
>  - the fact that your script has been written to run one and then exit,
>    so you may have a number of variables that aren't initialised
>    properly - this can produce unexpected errors
>
>  - ModPerl::Registry wraps your script in another sub, which may produce
>    unexpected closures (you would see warnings about variables not
>    remaining shared in your log)
>
> So if you move to using Registry, then you will need to check your
> scripts.
>
> However, using Registry means that your script is loaded and compiled
> once, avoiding this performance hit for subsequent requests - hence it
> runs faster.
>
> Have a look at this post that I wrote about gotchas under Registry, it
> may help you migrate:
> http://www.gossamer-threads.com/lists/modperl/modperl/94203#94203
>
> Clint
>
>
>


-- 
perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
")'

Re: how to use Apache::DBI

Posted by Clinton Gormley <cl...@traveljury.com>.
On Tue, 2007-07-31 at 10:09 +0800, Ken Perl wrote:
> I didn't run it under ModPerl::Registry, is there any risk to use the
> module? maybe I have to run lots of testing to the existing scripts.
> 


There is a risk to using this module, but also a significant benefit:
speed.

The risks come from:

 - the fact that your script has been written to run one and then exit, 
   so you may have a number of variables that aren't initialised 
   properly - this can produce unexpected errors

 - ModPerl::Registry wraps your script in another sub, which may produce
   unexpected closures (you would see warnings about variables not 
   remaining shared in your log)

So if you move to using Registry, then you will need to check your
scripts.

However, using Registry means that your script is loaded and compiled
once, avoiding this performance hit for subsequent requests - hence it
runs faster.

Have a look at this post that I wrote about gotchas under Registry, it
may help you migrate:
http://www.gossamer-threads.com/lists/modperl/modperl/94203#94203

Clint
 


Re: how to use Apache::DBI

Posted by Ken Perl <ke...@gmail.com>.
I didn't run it under ModPerl::Registry, is there any risk to use the
module? maybe I have to run lots of testing to the existing scripts.

Could I just run use the previous connections via DBI->connect_cache
instead of the Apache::DBI in one single cgi script(but the script
will call other modules which may make new db connections with same db
password and attributes)? In my testing, I saw some different database
handlers returned instead of the same hash reference address.

On 7/30/07, Clinton Gormley <cl...@traveljury.com> wrote:
> On Mon, 2007-07-30 at 18:21 +0800, Ken Perl wrote:
> > I've configured  the Apache::DBI in httpd.conf like this,
> >
> > PerlModule Apache::DBI
> >
> > I didn't have  Apache::DBI->connect_on_init($data_source, $username,
> > $auth, \%attr) in startup.pl since we don't use startup.pl. and the
> > doc says to config it in httpd.conf is OK.
> >
> > my question is I can not find any persistent connections for my CGI
> > script. any usage error here?
>
> Persistent connections will not work for straight CGI scripts, because
> CGI is not persistent.
>
> For each CGI request, a new perl interpreter is loaded, your script is
> compiled, run, and the Perl process exits.
>
> mod_perl IS persistent, as are your CGI scripts run via
> ModPerl::Registry etc.
>
> You don't need connect_on_init to work, but you do need mod_perl
>
> Clint
> >
>
>


-- 
perl -e 'print unpack(u,"62V5N\"FME;G\!E<FQ`9VUA:6PN8V]M\"\@``
")'

Re: how to use Apache::DBI

Posted by Clinton Gormley <cl...@traveljury.com>.
On Mon, 2007-07-30 at 18:21 +0800, Ken Perl wrote:
> I've configured  the Apache::DBI in httpd.conf like this,
> 
> PerlModule Apache::DBI
> 
> I didn't have  Apache::DBI->connect_on_init($data_source, $username,
> $auth, \%attr) in startup.pl since we don't use startup.pl. and the
> doc says to config it in httpd.conf is OK.
> 
> my question is I can not find any persistent connections for my CGI
> script. any usage error here?

Persistent connections will not work for straight CGI scripts, because
CGI is not persistent.

For each CGI request, a new perl interpreter is loaded, your script is
compiled, run, and the Perl process exits.

mod_perl IS persistent, as are your CGI scripts run via
ModPerl::Registry etc.

You don't need connect_on_init to work, but you do need mod_perl

Clint
>