Re: WTD: Wiki page
[prev]
[thread]
[next]
[Date index for 2005/04/16]
On Fri, Apr 15, 2005 at 09:52:11PM +0100, Ian McDonald-ONLINE wrote:
> I could really do with reading:
> http://www.class-dbi.com/cgi-bin/wiki/index.cgi?UsingWithModPerl
> But the Wiki has been down this week.
On Tue, 26 Oct 2004 16:19:10 -0400, PerrinHarkins posted the following on the mailing list:
I plan to submit a patch for Ima::DBI to fix this, but in the meantime I
am handling it by overriding db_Main and doing the connections myself.
Here's the code I use:
my $db_options = {
RaiseError => 1,
AutoCommit => 0,
FetchHashKeyName => 'NAME_lc',
ShowErrorStatement => 1,
ChopBlanks => 1,
RootClass => 'DBIx::ContextualFetch'
};
# override default to avoid using Ima::DBI closure
sub db_Main {
my $dbh;
if ( $ENV{'MOD_PERL'} and !$Apache::ServerStarting ) {
$dbh = Apache->request()->pnotes('dbh');
}
if ( !$dbh ) {
# $config is my config object. replace with your own settings...
$dbh = DBI->connect_cached(
$config->get('DbDSN'), $config->get('DbUser'),
$config->get('DbPass'), $db_options
);
if ( $ENV{'MOD_PERL'} and !$Apache::ServerStarting ) {
Apache->request()->pnotes( 'dbh', $dbh );
}
}
return $dbh;
}
sub dbi_commit {
my $self = shift;
$self->db_Main()->commit();
}
sub dbi_rollback {
my $self = shift;
$self->db_Main()->rollback();
}
Note that it was necessary to override dbi_commit and dbi_rollback as well because now Ima::DBI doesn't know about this
handle. I also stashed the handle in pnotes() for some extra speed because Class::DBI requests it so frequently. Stash
ing in pnotes() is safe because it gets cleared out at the end of each request even if your code dies. Make sure you ke
ep the other db options intact or various things in Class::DBI will break.
-- PerrinHarkins
----
In the AtomicUpdates node, ChrisHutchinson noted the following:
Defining db_Main() in a class to define a dynamic connection means that 'Main' doesn't appear in the Ima::DBI db_names()
list, and so doesn't get committed or rolled back in calls to dbi_commit()/dbi_rollback().
A work-around (as of Ima::DBI v 0.33) is to put this in the class:
__PACKAGE__->_remember_handle('Main');
-- ChrisHutchinson
That means you may not need to override dbi_commit() and dbi_rollback(), as in Perrin's code above, if you are using Ima
::DBI 0.33 or higher and call the _remember_handle() method in your db_Main() method.
----
On Thu, 10 Feb 2005 18:42:35 -0500, EdwardSabol posted the following reply to the mailing list:
For getting automatic rollbacks working, I propose the following solution which requires modifying Apache::DBI. First, a
dd the following sub to Apache/DBI.pm:
sub modperl_cleanup {
my $prefix = "$$ Apache::DBI ";
print STDERR "$prefix PerlCleanupHandler \n" if $Apache::DBI::DEBUG > 1;
my $dbh = $Connected{$Idx};
if ($dbh and $dbh->{Active} and !$dbh->{AutoCommit} and eval {$dbh->rollback}) {
print STDERR "$prefix PerlCleanupHandler rollback for $Idx \n" if $Apache::DBI::DEBUG > 1;
}
1;
}
You might notice that this is rather similar to Apache::DBI::cleanup(), but the logic is somewhat different. Apache::DBI
::cleanup() only rolls back when $Apache::DBI::Rollback{$Idx} is set which, due to the way Ima::DBI works, only happens
on the first request.
Then, in your mod_perl httpd.conf file, add the following:
PerlCleanupHandler Apache::DBI::modperl_cleanup
That fix should work with all DBI connections, not just Class::DBI stuff, I believe.
In an off-list e-mail discussion that Perrin and I had on this topic a few months ago, Perrin suggested a simpler soluti
on:
$r->push_handlers(PerlCleanupHandler => sub {
MyClassDBI->dbi_rollback();
});
-- EdwardSabol
----
If you try to load your Class::DBI modules with a PerlModule directive in httpd.conf, you may get an error like this:
foo method already exists in My::CDBI::Subclass
at /usr/share/perl5/Class/DBI/Relationship/HasMany.pm
line 13
The solution is to not use PerlModule for preloading. Pull in a startup.pl file instead and say "use My::CDBI::Subclass
" in there. Alternately, do this in your httpd.conf:
<Perl>
use Domain::DBI;
</Perl>
The problem is that PerlModule is trying to load this module again when apache restarts (it starts twice when you start
it, as the docs
explain).
-- PerrinHarkins
Tony
|
|
Re: WTD: Wiki page
Tony Bowden 07:49 on 16 Apr 2005
|