Как получить другой дескриптор, используя clone () на дескриптор БД, созданный connect_cache? - PullRequest
1 голос
/ 04 мая 2020

Достопочтенный Жюри!

Я обнаружил проблему с 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

...