2015-04-03 94 views
1

我的組織有一個自定義軟件包用於連接到我們的數據庫服務器,該服務器負責隨機嘗試各種鏡像(根據配置文件),並且只嘗試主數據庫服務器進行非只讀連接,或者如果沒有鏡子可以到達。我想採取並使用它在Catalyst應用程序內具有持久連接。與Catalyst的持久數據庫連接

我試過的是創建一個基於Catalyst :: Model :: DBI的Model包,但重新定義了模塊的connect()方法來使用我們的包的連接方法。然後,我重新定義了使用stay_connected()的「selectall_arrayref」,「do」方法......它工作正常,但它爲每個查詢創建一個新的連接 - 即使在相同的http請求中 - 儘管催化劑::型號:: DBI似乎暗示連接應該持久。

所以我的問題是,應該發生什麼?我需要做一些不同的事情來獲得一個持久的句柄嗎? Model :: DBI通常會提供這個功能嗎?如果是的話,我如何將我們的這個東西嫁入它,還是有一個更簡單的方法?我不想重寫我們的整個包來使用DBIx :: Class,我只想插入我們的例程,該例程爲我提供了適合我們系統的數據庫句柄。

package SpamControl::Model::Database; 
use strict; 
use Freecycle::Database; 

use base 'Catalyst::Model::DBI'; 

# redefine the connect method, this is just copied from Model::DBI but using the Freecycle package for the actual connection. 
sub connect { 
    my $self = shift; 
    my $dbh; 
    # TODO: I wish this could be a persistent connection. 
    eval { 
      $dbh = Freecycle::Database::connect({ username => 'member', read_only => 1 }); 
    }; 
    if ([email protected]) { $self->{log}->debug(qq{Couldn't connect to the database "[email protected]"}) if $self->{debug} } 
    else { $self->{log}->debug ('Connected to the database') if $self->{debug}; } 
    $self->_pid($$); 
    $self->_tid(threads->tid) if $INC{'threads.pm'}; 
    return $dbh; 
} 

# for read/write connections 
sub dbh_admin { 
    my ($self,$c) = @_; 
    my $dbh = Freecycle::Database::connect({ username => 'admin', read_only => 0 }); 
    return $dbh; 
} 

sub do { 
    my $self = shift; 
    return $self->dbh_admin->do(@_); 
} 

sub selectall_hashref { 
    my $self = shift; 
    return $self->stay_connected->selectall_hashref(@_); 
} 

...etc etc. 

回答

2

Catalyst::Model::DBI提供持久連接和自動再連接(通過DBIx::Connector現今)。

如果您已經是做(Freecycle::Database?),你不應該使用Catalyst::Model::DBI可言,而是用你的模塊作爲催化劑的模型,這Catalyst::Model::Adaptor可以幫助很多的模塊。

+0

也許我不清楚,但我所做的只是擴展Catalyst :: Model :: DBI,因爲我們的模塊不處理持久性等。它只是使用正確的憑證來處理連接到正確的數據庫(master,slaves或fallback)。我看着催化劑::模型::適配器,它看起來比我需要的更多。或更少。 – steev 2015-04-06 16:44:03

+2

也許我還不清楚:使用Catalyst :: Model :: DBI(CMD)意味着你應該讓它連接到DBMS。如果你自己建立連接,那麼你正在接受CMD的腳趾。對CMD進行子類化可能是一個可行的想法,但這應該僅限於增加前面的「循環」邏輯來選擇數據庫DSN和憑證IMO(循環只會在應用程序啓動時發生,或者在重新連接的情況下才會發生,想要持久性)。 請看看以下關於CMD預期用法的CMD doc片段(第2段): https://metacpan.org/pod/Catalyst::Model::DBI#DESCRIPTION – emazep 2015-04-07 11:27:42

+1

感謝您的澄清。所以它看起來像催化劑::模型::適配器是唯一的出路。但閱讀文檔,因爲我的模塊不是一個適當的對象類(它只是連接和回傳一個dbh),它看起來像除非我想重寫它,我可能不得不將它包裝在另一個模塊中創建一個對象,然後使用CMA來「包裝」那個。這感覺很煩人,但也許這是唯一的方法。 – steev 2015-04-08 17:34:54