重复的DBI连接不适用于Perl 5.24.0中的词法变量

Drt*_*mDe 7 perl scope dbi

当我将perl环境从5.16.0切换到5.24.0时,我得到了一个我无法理解的奇怪行为.这段代码

use DBI;

my $conn   = 'dbi:ODBC:sqlserver_xxxx';  
my $userid = 'dw_select';  
my $passwd = 'xxxx';

for ( 1 .. 100 ) {
    warn "start try $_";
    my $dbh = DBI->connect($conn, $userid, $passwd, { RaiseError => 1 } );
    warn "end try $_";  
}
Run Code Online (Sandbox Code Playgroud)

在5.16.0上运行正常,但当切换到5.24.0时,我得到以下结果:

start try 1 at test_con.pl line 9.
end try 1 at test_con.pl line 11.
start try 2 at test_con.pl line 9.
end try 2 at test_con.pl line 11.
start try 3 at test_con.pl line 9.
DBI connect('sqlserver_xxxx','dw_select',...) failed: 
 Unable to fetch information about the error at test_con.pl line 10.
Run Code Online (Sandbox Code Playgroud)

通过此修改,它可以再次运行无错误:

use DBI;

my $conn   = 'dbi:ODBC:sqlserver_xxxx';  
my $userid = 'dw_select';  
my $passwd = 'xxxx';

my $dbh;    
for ( 1 .. 100 ) {
    warn "start try $_";
    $dbh = DBI->connect($conn, $userid, $passwd, { RaiseError => 1 } );
    warn "end try $_";  
}
Run Code Online (Sandbox Code Playgroud)

你有没有人对此有解释?

jjo*_*ohn 0

这是一个紧密的循环。我可能会尝试稍微重写一下,看看是否有帮助:

for ( 1 .. 100 ) {
   warn "start try $_";
   my $dbh = DBI->connect($conn, $userid, $passwd, { RaiseError => 1 } );
   if (!$dbh) {
       warn("Try $_ connect: " . $DBI::ERRSTR . "\n");
       last;
   }
   $dbh->disconnect;
}
Run Code Online (Sandbox Code Playgroud)

ODBC 接口可能无法在如此短的时间内很好地处理单个线程中这么多句柄的实例化。运气好的话,明确的断开连接会有帮助。

干杯。