[CDBI] Re: Transaction over parent and children has_a objects

Peter Speltz peterspeltz at gmail.com
Wed Apr 5 16:39:39 BST 2006


> What happens if you replace your call to $class->dbi_rollback with this:
> $class->db_Main->rollback()
>

Same thing. Figured it out though. When i removed an Ima::DBI patch i
got from you in email it worked.  I'm using Modperl 2.0.2 . Could be a
bug in there or something. Here is patch i had. Error could have been
in me patching also but you made it pretty fool proof cut and paste.

Now i have potential mod perl issues with Apache::DBI.  I've heard it
should only  be an issue as long as you dont have any db connections
made before apache forks at startup. That sound right?   Otherwise,
the db_Main method on the wiki could work and i could load my modules
at startup?

here is patch i had on Ima::DBI

################## diff -u Ima/DBI.pm /usr/lib/perl5/our_perl/Ima/DBI.pm.perrin
--- Ima/DBI.pm  2005-09-05 04:16:44.000000000 -0500
+++ /usr/lib/perl5/our_perl/Ima/DBI.pm.perrin   2006-04-05
04:53:51.000000000 -0500
@@ -2,6 +2,10 @@

 $VERSION = '0.34';

+# pjs -- 10-18-05 patched with Perrins Modperl patch from list so it
plays nice with
+# Apache::DBI
+#
+#
 use strict;
 use base 'Class::Data::Inheritable';
 use DBI;
@@ -305,15 +309,46 @@
        $class->__Database_Names($handles);
 }

+
+# original
+#sub _mk_db_closure {
+#      my ($class, @connection) = @_;
+#      my $dbh;
+#      return sub {
+#              unless ($dbh && $dbh->FETCH('Active') && $dbh->ping) {
+#                      $dbh = DBI->connect_cached(@connection);
+#              }
+#              return $dbh;
+#      };
+#}
+
+#pjs -- patched *  perrin's good version to be in Ima::DBI one day
 sub _mk_db_closure {
-       my ($class, @connection) = @_;
+       my ($class, $dsn, $user, $pass, $attr) = @_;
+       $attr ||= {};
+
        my $dbh;
+       my $process_id = $$;
        return sub {
-               unless ($dbh && $dbh->FETCH('Active') && $dbh->ping) {
-                       $dbh = DBI->connect_cached(@connection);
+               # set the PID in a private cache key to prevent us
+               # from sharing one with the parent after fork.  This
+               # is better than disconnecting the existing $dbh since
+               # the parent may still need the connection open.  Note
+               # that forking code also needs to set InactiveDestroy
+               # on all open handles in the child or the connection
+               # will be broken during DESTROY.
+               $attr->{private_cache_key_pid} = $$;
+
+               # reopen if this is a new process or if the connection
+               # is bad
+           if ($process_id != $$ or
+               not ($dbh && $dbh->FETCH('Active') && $dbh->ping)) {
+               $dbh = DBI->connect_cached($dsn, $user, $pass, $attr);
+                       $process_id = $$;
                }
-               return $dbh;
-       };
+
+       return $dbh;
+       }
 }

###############################

thank all.
--
pjs




More information about the ClassDBI mailing list