2015-04-03 95 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