You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Matthew Lineen <ma...@lineen.com> on 2005/11/08 19:10:58 UTC
mp1, mason, apache::dbi multiple database issue
Hello,
I wasn't sure if I should post here, on the Mason list, or elsewhere;
hopefully someone here can help.
I'm using mp1, Mason, Apache::DBI, and MySQL InnoDB tables.
When adding a second database connection to our code, a very simple
getUserIdFromSession subroutine returns inconsistent values. Removing
the second connection fixes the problem.
I added warnings inside the getUserIdFromSession subroutine (below) to
track down where the problem might be, but:
- the DBH connection is always to the proper database (I printed out a
SHOW TABLES statement).
- it always receives the cookie value correctly
- it always falls into the else { return $userId; } portion
- sometimes it returns the value, other times it returns undef
While connected outside of apache to the database server, I can see the
record in the tUserSession table using the same SQL statement the code
is using.
If I simply comment out the connection to $dbhEmail in the autohandler,
the problem goes away, and the subroutine always returns the proper value.
I've been scratching my head for awhile on this one, but can't see why
adding another global and a different connection would cause this.
Thanks in advance,
Matthew
httpd.conf
----------
PerlAddVar MasonAllowGlobals $dbh
PerlAddVar MasonAllowGlobals $dbhEmail
startup.pl
----------
use Apache::DBI ();
use DBI ();
use DBD::mysql ();
autohandler
-----------
<%once>
use Apache::Cookie qw();
use Foo::Auth;
use Foo::Constants;
use Foo::User;
</%once>
<%init>
$dbh =
DBI->connect("DBI:mysql:$CONSTANTS{DB_BASE}content:$CONSTANTS{DB_HOST}",
$CONSTANTS{DB_USER}, $CONSTANTS{DB_PASS},
{AutoCommit => 0, RaiseError => 1, PrintError => 0}
) or die "ERROR: Cannot connect to database";
$dbhEmail =
DBI->connect("DBI:mysql:$CONSTANTS{DB_BASE}email:$CONSTANTS{DB_HOST}",
$CONSTANTS{DB_USER}, $CONSTANTS{DB_PASS},
{AutoCommit => 0, RaiseError => 1, PrintError
=> 0}
) or die "ERROR: Cannot connect to database";
</%init>
<%perl>
my(%cookies) = Apache::Cookie->fetch();
# -- login session --
my($userId) = getUserIdFromSession($dbh, \%cookies);
my($userObject) = undef;
if (defined($userId)) {
$userObject = Foo::User->new()->init($dbh);
unless ($userObject->load(\@errors, $userId)) {
$userObject = undef;
}
}
</%perl>
<% $m->call_next( userObject => $userObject ) %>
Foo/Auth.pm
-----------
package Foo::Auth;
@ISA = qw( Exporter );
use strict;
use warnings;
our($SESSION_COOKIE_NAME) = 'user_session';
our($SESSION_KEY_LENGTH) = 50;
our(@EXPORT) = qw( $SESSION_KEY_LENGTH getUserIdFromSession
doLogin );
sub getUserIdFromSession {
my($dbh, $rCookies) = @_;
croak 'API' unless defined($dbh);
croak 'API' unless defined($rCookies) && ref($rCookies) eq 'HASH';
my($cookie) = $rCookies->{$SESSION_COOKIE_NAME};
return undef unless defined($cookie);
my($sessionKey) = $cookie->value();
return undef unless defined($sessionKey) && length($sessionKey) ==
$SESSION_KEY_LENGTH;
my($userId) = eval {
return $dbh->selectrow_array(q{
SELECT userId
FROM tUserSession
WHERE sessionKey=? AND expiresOn>NOW()
}, undef, $sessionKey);
};
if ($@) {
return undef;
} else {
return $userId;
}
}
sub doLogin {
my($dbh, $rErrors, $username, $ip) = @_;
my($sessionKey) = _createSessionKey();
eval {
my($userId) = $dbh->selectrow_array(q{
SELECT userId
FROM tUser
WHERE userName=?
}, undef, $username);
$dbh->do(q{
INSERT INTO tUserSession (sessionKey, userId, createdOn,
createdIp, expiresOn)
VALUES (?,?,NOW(),?,ADDDATE(NOW(), INTERVAL 1 DAY))
}, undef, $sessionKey, $userId, $ip);
$dbh->commit();
};
if ($@) {
push @$rErrors, $@;
eval { $dbh->rollback() };
push @$rErrors, $@ if $@;
return undef;
} else {
return $sessionKey;
}
}
1;
Re: mp1, mason, apache::dbi multiple database issue
Posted by Perrin Harkins <pe...@elem.com>.
On Tue, 2005-11-08 at 12:10 -0600, Matthew Lineen wrote:
> I'm using mp1, Mason, Apache::DBI, and MySQL InnoDB tables.
Check your isolation level:
http://perl.apache.org/docs/1.0/guide/databases.html#Transactions_Not_Committed_with_MySQL_InnoDB_Tables
- Perrin