Достопочтенный Жюри!
Я обнаружил проблему с Perl DBI, которая может быть либо ошибкой, либо функцией. Бьюсь об заклад первым. :)
Я обнаружил, что $ dbh-> clone () возвращает то же самое $dbh
, если оно создано DBI-> connect_cached () .
Вот пример кода:
use strict;
use warnings;
use DBI 1.614;
my %attr = (PrintError => 1);
my @conn = ('DBI:Oracle:MYSERVER', 'Solaris', '****', \%attr);
print "#### Simple connect ############################################\n";
{
my $dbh1 = DBI->connect(@conn); print $dbh1,"\n";
my $dbh2 = DBI->connect(@conn); print $dbh2,"\n";
my $dbh3 = $dbh1->clone(\%attr); print $dbh3,"\n";
}
print "#### Cached connect ############################################\n";
{
my $dbh1 = DBI->connect_cached(@conn); print $dbh1,"\n";
my $dbh2 = DBI->connect_cached(@conn); print $dbh2,"\n";
my $dbh3 = $dbh1->clone(\%attr); print $dbh3,"\n";
}
print "#### Cached connect with private ###############################\n";
{
$attr{private_data} = 1;
my $dbh1 = DBI->connect_cached(@conn); print $dbh1,"\n";
$attr{private_data} = 2;
my $dbh2 = DBI->connect_cached(@conn); print $dbh2,"\n";
$attr{private_data} = 3;
my $dbh3 = $dbh1->clone(\%attr); print $dbh3,"\n";
}
print "#### END #######################################################\n";
И вывод:
#### Simple connect ############################################
DBI::db=HASH(0x27ec838)
DBI::db=HASH(0x27ed138)
DBI::db=HASH(0x2b53638)
#### Cached connect ############################################
DBI::db=HASH(0x28863d8)
DBI::db=HASH(0x28863d8)
DBI::db=HASH(0x28863d8)
#### Cached connect with private ###############################
DBI::db=HASH(0x27ec880)
DBI::db=HASH(0x2b53e48)
DBI::db=HASH(0x27ec880)
#### END #######################################################
- Простой
connect
работает, как я ожидал. Новое подключение к одной и той же службе / пользователь возвращает разные $dbh
и clone () одинаковые. - Кэшированное подключение также работает, как и ожидалось. То же самое
$dbh
возвращается во всех 3 случаях. - Наконец, я применил атрибут private_ *, как указано в документации в connect_cached . Он работает только для вызовов
connect_cached
, но предоставление уникального атрибута для clone
не дает нового дескриптора DBI, как я ожидал, основываясь на описании clone . Но, возможно, мои ожидания неверны.
Реальная проблема заключается в том, что я хотел бы реализовать решение fork () . Я установил AutoInactiveDestroy для всех вновь созданных $dbh
с, и все работает нормально, за исключением того, что я не могу получить уникальный дескриптор для существующего $dbh
, созданного connect_cached в родительском процессе напротив, я установил атрибут private_pid
равным pid текущего процесса. Я проверил источник DBI.pm
и клон вызывает внутренние dbi_connect_closure
исходного $dbh
, и это закрытие вызывает connect
или connect_cached
методы, основанные на исходном методе подключения $dbh
, Итак, я думаю, что он должен рассмотреть уникальный атрибут private_*
и вернуть новый $dbh
.
В качестве обходного пути я делаю connect_cashed
каждый раз вместо вызова clone
.
Пожалуйста, поделитесь любой информацией, которая может помочь решить или обойти проблему.
Версии:
Perl : v5.26.2
DBI : 1.641
Linux: 3.10.0-1127.el7.x86_64
Заранее спасибо! Truey