Я предпочитаю второй. В то время как Ваши тесты, возможно, хорошо работали, , Murphy говорит, что что-то неожиданное пойдет не так, как надо. Так, вместо того, чтобы получить исключение в фактическом ошибочном вызове метода, Вы заканчиваете тем, что проследили NullPointerException (или эквивалентный) 10 стековых фреймов глубже.
Полупрозрачно существует DBIx :: Class :: Cursor :: Cached (из mst, как DBIC). Однако вам необходимо предоставить объект Cache для ваших подключений или объектов схемы. К сожалению, выглядит очень недокументированным.
В Cookbook есть пример использования Tie :: Cache в DBIC, а также есть функции (get | set | clear) _cache в DBIx :: Class :: ResultSet, но они, вероятно, не совсем то, что вам нужно .
Вот простой способ добавить кеширование с помощью CHI . На самом деле я этого не пробовал, поэтому могут быть подводные камни, которые я не учел, особенно в отношении сериализации наборов результатов DBIC.
package My::Table;
use strict;
use warnings;
use base 'DBIx::Class';
use Storable 'freeze';
use CHI;
$Storable::canonical = 1;
__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table('mytable');
# ....
my $CACHE = CHI->new( driver => 'Memory' );
sub search {
my $self = shift;
my $key = freeze( \@_ ); # make cache key from params
if ( my $rs = $CACHE->get( $key ) ) {
return $rs;
}
# Note: there are issues with context propagation here
my $rs = $self->next::method( @_ );
$CACHE->set( $key => $rs );
return $rs;
}
sub update {
my $self = shift;
my @keys = $self->find_all_cache_items_affected_by_this_update( @_ );
$CACHE->remove( $_ ) for @keys;
$self->next::method( @_ );
}
Это немного неуклюже, но я думаю, что это хорошая отправная точка. Если вы выполните такие действия в базовом классе для всех классов таблиц DBIx :: Class, вы сможете довольно легко создать прозрачное кэширование.