2010-06-15 42 views
3

我有一个基于mod_perl2的web应用程序需要连接到mysql数据库。我已经在一个驼鹿角色中实现了SQL连接细节。与mod_perl2 moose应用程序的数据库连接太多

简体,作用如下所示:

package Project::Role::SQLConnection; 

use Moose::Role; 
use DBIx::Connector; 

has 'connection' => (is => 'rw', lazy_build => 1); 
has 'dbh' => (is => 'rw', lazy_build => 1); 
has 'db' => (is => 'rw', default => 'alcatelRSA'); 
has 'port' => (is => 'rw', default => 3306); 
has 'host' => (is => 'rw', default => '10.125.1.21'); 
has 'user' => (is => 'rw', default => 'tools'); 
has 'pwd' => (is => 'rw', default => 'alcatel'); 


#make sure connection is still alive... 
before dbh => sub { 
    my $self = shift; 
    $self->connection->run(fixup => sub { $_->do('show tables') }); 
}; 

sub _build_dbh { 
    my $self = shift; 
    return $self->connection->dbh; 
} 

sub _build_connection { 
    my $self = shift; 
    my $dsn = 'DBI:mysql:'.$self->db.';host='.$self->host.';port='.$self->port; 
    my $conn = DBIx::Connector->new($dsn, $self->user, $self->pwd); 
    return $conn; 
} 

no Moose::Role; 
1; 

我然后在需要与

with qw(Project::Role::SQLConnection); 

语句的数据库连接的所有驼鹿类使用这个角色。

虽然这在很少的对象被创建的时候效果很好,但当很多对象被创建时,我很快就会遇到麻烦。在httpd的日志举例来说,我得到的错误:

DBI connect('alcatelRSA;host=10.125.1.21;port=3306','tools',...) failed: Too many connections at C:/Perl/site/lib/DBIx/Connector.pm line 30

我想过使用DBIx ::连接“断开”调用来关闭每次与数据库的连接,但对性能的影响似乎严重开/根据需要关闭连接。

您对这个问题有其他建议吗?

回答

6

您是否正在复制dbh并在DBIx::Connector对象超出范围时在地方使用它?该文件明确表示不这样做。相反,请保存DBIx :: Connector对象本身,然后使用该属性中的handles选项将方法调用委托给它。

这是我做的(其实我只是张贴了这个代码昨天在回答另一个问题;有趣的DB问题怎么进来的包):

has dbixc => (
    is => 'ro', isa => 'DBIx::Connector', 
    lazy_build => 1, 
    # DO NOT save a copy of the dbh. Use this accessor every time, as 
    # sometimes it will change unexpectedly! 
    handles => [ qw(dbh) ], 
); 

sub _build_dbixc 
{ 
    my $this = shift; 
    DBIx::Connector->new(
     $this->dsn, 
     $this->username, 
     $this->password, 
     $this->connect_options, 
    ); 
} 

sub call_dbh 
{ 
    my $this = shift; 
    my $method = shift; 
    my @args = @_; 

    # the normal behaviour -- pings on every dbh access 
    #return $this->dbh->$method(@args); 

    # the smart behaviour -- presume the DB connection still works 
    $this->dbixc->run(fixup => sub { $_->$method(@args) }); 
} 

你也可能想看看有多少的mod_perl进程你允许。每个单独的进程或线程都必须有自己的数据库连接,但可能有多个连接 - 所以您可能还需要确保上面的代码仅运行(即构建db管理对象),每个进程只有一次 ,并且随后每次构建这样一个对象的尝试都会返回现有对象的副本。一个简单的方法是使用MooseX::Singleton,但这会引入其他设计问题。

+1

谢谢,我真的很喜欢这个代码,但它仍然不能解决“太多连接..”的问题。我怀疑,对于手头的问题,设计只是要求将某个角色的数据库连接封装起来,这是因为创建的对象太多。 – 2010-06-18 10:16:37

相关问题