我的組織有一個自定義軟件包用於連接到我們的數據庫服務器,該服務器負責隨機嘗試各種鏡像(根據配置文件),並且只嘗試主數據庫服務器進行非只讀連接,或者如果沒有鏡子可以到達。我想採取並使用它在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.
也許我不清楚,但我所做的只是擴展Catalyst :: Model :: DBI,因爲我們的模塊不處理持久性等。它只是使用正確的憑證來處理連接到正確的數據庫(master,slaves或fallback)。我看着催化劑::模型::適配器,它看起來比我需要的更多。或更少。 – steev 2015-04-06 16:44:03
也許我還不清楚:使用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
感謝您的澄清。所以它看起來像催化劑::模型::適配器是唯一的出路。但閱讀文檔,因爲我的模塊不是一個適當的對象類(它只是連接和回傳一個dbh),它看起來像除非我想重寫它,我可能不得不將它包裝在另一個模塊中創建一個對象,然後使用CMA來「包裝」那個。這感覺很煩人,但也許這是唯一的方法。 – steev 2015-04-08 17:34:54