Re: WTD: Wiki page

[prev] [thread] [next] [Date index for 2005/04/16]

From: Tony Bowden
Subject: Re: WTD: Wiki page
Date: 07:49 on 16 Apr 2005
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

WTD: Wiki page
Ian McDonald-ONLINE 20:52 on 15 Apr 2005

Re: WTD: Wiki page
Tony Bowden 07:47 on 16 Apr 2005

Re: WTD: Wiki page
William Ross 11:32 on 18 Apr 2005

Re: WTD: Wiki page
Tony Bowden 12:08 on 20 Apr 2005

Re: WTD: Wiki page
William Ross 11:52 on 18 Apr 2005

weird dbix error
yoorobot 19:46 on 18 Apr 2005

Re: WTD: Wiki page
Tony Bowden 07:49 on 16 Apr 2005

Generated at 09:29 on 27 Apr 2005 by mariachi v0.52