2010-06-15 66 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

相關問題