我的组织有一个自定义软件包用于连接到我们的数据库服务器,该服务器负责随机尝试各种镜像(根据配置文件),并且只尝试主数据库服务器进行非只读连接,或者如果没有镜子可以到达。我想采取并使用它在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