Thanks for the suggestion, but it's the same connection with the same params every time. The connection code is actually in a Class::DBI module, which gets use()'d by all of my scripts. This module isn't in my startup script, so that each process keeps its own copy. So there are multiple handles, but they should all be identical and used by different interpreters.

Upon further investigation I've found that the rollback is only executing once for each server process, and never again after that. That's true even *without* the bad SQL and transaction aborted erors. I'm assuming that isn't the intended behavior...

Also, I read on some newsgroup that cleanups don't run if there's been a 500 error or the user hit the 'stop' button. If true, why not? Isn't following an error the best possible time to execute cleanup code? Is there a way, either with the mod_perl API or some standard perl trick, to force the server to run additional code after such an error?



Joe Thomas wrote:

Do you ever connect to a different database from your mod_perl scripts -- or to the same database with different options? Or even use a different form for the database hostname (hostname only vs. fully-qualified domain name)?

If you do, please try this patch (inline and attached) against the current Apache::DBI. I believe it fixes a bug in rolling back transactions when more than one database handle is used.

Joe

--- DBI.pm.orig Tue Feb 17 16:18:50 2004
+++ DBI.pm Tue Aug 31 14:48:58 2004
@@ -21,7 +21,6 @@
my %Rollback; # keeps track of pushed PerlCleanupHandler which can do a rollback after the request has finished
my %PingTimeOut; # stores the timeout values per data_source, a negative value de-activates ping, default = 0
my %LastPingTime; # keeps track of last ping per data_source
-my $Idx; # key of %Connected and %Rollback.



# supposed to be called in a startup script. @@ -67,7 +66,7 @@ my $dsn = "dbi:$drh->{Name}:$args[0]"; my $prefix = "$$ Apache::DBI ";

- $Idx = join $;, $args[0], $args[1], $args[2];
+ my $Idx = join $;, $args[0], $args[1], $args[2]; # key of %Connected and %Rollback.


# the hash-reference differs between calls even in the same
# process, so de-reference the hash-reference
@@ -96,7 +95,7 @@
# TODO - Fix mod_perl 2.0 here
if(!$Rollback{$Idx} and $needCleanup and Apache->can('push_handlers')) {
print STDERR "$prefix push PerlCleanupHandler \n" if $Apache::DBI::DEBUG > 1;
- Apache->push_handlers("PerlCleanupHandler", \&cleanup);
+ Apache->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) });
# make sure, that the rollback is called only once for every
# request, even if the script calls connect more than once
$Rollback{$Idx} = 1;
@@ -155,6 +154,7 @@
# Note: the PerlCleanupHandler runs after the response has been sent to the client


sub cleanup {
+ my $Idx = shift;
my $prefix = "$$ Apache::DBI ";
print STDERR "$prefix PerlCleanupHandler \n" if $Apache::DBI::DEBUG > 1;
my $dbh = $Connected{$Idx};



------------------------------------------------------------------------


--- DBI.pm.orig Tue Feb 17 16:18:50 2004
+++ DBI.pm Tue Aug 31 14:48:58 2004
@@ -21,7 +21,6 @@
my %Rollback; # keeps track of pushed PerlCleanupHandler which can do a rollback after the request has finished
my %PingTimeOut; # stores the timeout values per data_source, a negative value de-activates ping, default = 0
my %LastPingTime; # keeps track of last ping per data_source
-my $Idx; # key of %Connected and %Rollback.
# supposed to be called in a startup script.
@@ -67,7 +66,7 @@
my $dsn = "dbi:$drh->{Name}:$args[0]";
my $prefix = "$$ Apache::DBI ";
- $Idx = join $;, $args[0], $args[1], $args[2];
+ my $Idx = join $;, $args[0], $args[1], $args[2]; # key of %Connected and %Rollback.
# the hash-reference differs between calls even in the same
# process, so de-reference the hash-reference @@ -96,7 +95,7 @@
# TODO - Fix mod_perl 2.0 here
if(!$Rollback{$Idx} and $needCleanup and Apache->can('push_handlers')) {
print STDERR "$prefix push PerlCleanupHandler \n" if $Apache::DBI::DEBUG > 1;
- Apache->push_handlers("PerlCleanupHandler", \&cleanup);
+ Apache->push_handlers("PerlCleanupHandler", sub { cleanup($Idx) });
# make sure, that the rollback is called only once for every # request, even if the script calls connect more than once
$Rollback{$Idx} = 1;
@@ -155,6 +154,7 @@
# Note: the PerlCleanupHandler runs after the response has been sent to the client
sub cleanup {
+ my $Idx = shift;
my $prefix = "$$ Apache::DBI ";
print STDERR "$prefix PerlCleanupHandler \n" if $Apache::DBI::DEBUG > 1;
my $dbh = $Connected{$Idx};





--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html



Reply via email to