【发布时间】:2020-08-18 18:22:23
【问题描述】:
尊敬的评审团!
我发现 Perl DBI 的一个问题可能是错误或功能。我赌第一个。 :)
我发现$dbh->clone() 如果由DBI->connect_cached() 创建,则返回相同的$dbh。
示例代码如下:
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() 类似。 - 缓存连接也可以按预期工作。在所有 3 个案例中都返回了相同的
$dbh。 - 最后我应用了一个 private_* 属性,如connect_cached 中的文档所述。它仅适用于
connect_cached调用,但根据clone 的描述,为clone提供唯一属性并没有像我预期的那样提供新的DBI 句柄。但也许我的期望是错误的。
真正的问题是我想实现一个fork() 证明解决方案。我为所有新创建的$dbhs 设置了AutoInactiveDestroy,一切正常,除了我无法在父进程中为connect_cached 创建的现有$dbh 获得唯一句柄,相反我设置了private_pid 属性等于当前进程的pid。我检查了DBI.pm 源,clone 调用了原始$dbh 的内部dbi_connect_closure,这个闭包基于原始$dbh 的connect 方法调用connect 或connect_cached 方法。所以,我认为它应该考虑唯一的private_* 属性并返回一个新的$dbh。
作为一种解决方法,我每次都调用connect_cashed,而不是调用clone。
请分享任何可能有助于解决或解决问题的信息。
版本:
Perl : v5.26.2
DBI : 1.641
Linux: 3.10.0-1127.el7.x86_64
提前致谢!没错
【问题讨论】:
-
@Pradeep 感谢您的提示! $dbh 是由其他模块创建的,所以我可以设置一些属性,但是我的代码没有完成连接。而且我无法安装新的 Perl 模块,因为环境不是我维护的。