【问题标题】:Cleanup of statement handlers in DBI perl在 DBI perl 中清理语句处理程序
【发布时间】:2017-06-24 07:36:44
【问题描述】:

我正在使用 DBI perl 连接 Sybase 数据服务器。我的流程在全天运行的循环中执行以下操作

Till end of day, do {
  $sth = $dbh->prepare
  execute query
  someAnotherPerlFunction()
  someAnotherPerlFunctionOne()
}

someAnotherPerlFunction()
{
   $sth = $dbh->prepare (select)
   execute query
}

someAnotherPerlFunctionOne()
{
   my $sth = undef;
   $sth = $dbh->prepare (update)
   execute query;
   undef $sth;
}

现在,鉴于这将全天运行,在资源清理方面我需要牢记哪些事项。

目前,我在每个函数之后都在做undef $sth,如 someAnotherPerlFunctionOne 所示。那有必要吗?

【问题讨论】:

  • someAnotherPerlFunctionOne 中的 undef 是不需要的。一旦超出范围,在函数内部定义的变量就是 undef。
  • 更重要的是数据库的句柄($dbh)。最终需要提交,如果在您的代码中关闭了 AutoCommit,或者如果您不保持持久连接,您可能需要调用 $dbh->disconnect。
  • 你为什么要问这个?你的程序有问题吗?如果是,请说明问题,否则保持原样。
  • @JohnDoe:我们通常通过测试来做到这一点。
  • @user3606329:"如果您的代码中关闭了 AutoCommit ...您可能想调用 $dbh->disconnect" 断开连接似乎有点奇怪,这将丢弃所做的所有更改。提交事务的方式是调用$dbh->commit,但AutoCommit默认是on,所以可以合理地假设OP没有改变它。

标签: perl sybase dbi resource-cleanup


【解决方案1】:

Perl 会为您清理,但最好将您的数据库句柄传递给函数,而不是每次都重新创建它并立即销毁它。

【讨论】:

  • 谢谢。我在另一个包含在这个配置文件中的配置文件中创建了 dbhandler。因此,我不会一遍又一遍地创建 dbh。
  • @Kraken:这是一个句柄handler 是完全不同的东西。
  • @Borodin dbh 的句柄是否正确?这就是我在单独的配置中指定的内容。
  • @Kraken: $dbh 是一个数据库句柄;它是一个数据对象。 handler 是一段处理任何类型事件的代码。
【解决方案2】:

有几件事需要注意,但使用 undef 不是其中之一

  • 如果您的进程整天都在运行,那么您应该继续检查连接是否仍然有效。你可以使用$dbh->ping

  • 您应该prepare 每个语句只使用一次。之后你可以使用不同的绑定参数多次执行它

  • 如果您留下 SELECT 语句句柄而未获取其所有数据,则应调用 $sth->finish 将其重置

您的伪代码非常有限,并没有解释太多。特别是我不明白配置文件(数据文件)如何为您创建数据库句柄。因为您需要检查数据库连接是否仍然处于活动状态,所以您还需要能够在必要时重新连接。如果这是在“配置文件”中完成的,那么我认为您需要重新处理您的设计

这里有一个更 Perlish 的伪代码示例,说明我认为它应该如何工作。每次围绕until ( $end_of_day ) 循环,第一件事就是检查数据库句柄是否仍然有效。如果不是,那么那里是您应该建立连接和prepare所有语句句柄的时间点

之后,最好将数据库句柄和语句句柄都传递给任何子例程。您会注意到,一旦为每个语句句柄完成了prepare,这两个子例程就会折叠成相同的代码

这需要填写很多,但我对您的申请几乎一无所知。希望对你有帮助

use DBI;

my $dbh;

until ( $end_of_day ) {

    my ($sth, $select, $update);

    until ( $dbh and $dbh->ping ) {

        $dbh = DBI->connect(...);

        if ( $dbh ) {
            $select = $dbh->prepare('SELECT ...');
            $update = $dbh->prepare('UPDATE ...');
            $sth = $dbh->prepare('SOME SQL');
            last;
        }

        sleep 10; # Wait before retrying
    }

    $sth->execute();
    someAnotherPerlFunction($dbh, $select);
    someAnotherPerlFunctionOne($dbh, $update);
}

someAnotherPerlFunction {
    my ($dbh, $sth) = @_;
    $sth->execute;
}

someAnotherPerlFunctionOne {
    my ($dbh, $sth) = @_;
    $sth->execute;
}

【讨论】:

  • 谢谢。我正在执行以下操作,在 perl 脚本的开头我执行 require "$FindBin::Bin/dbconfig.pl"; 并且在 dbconfig 中我有 dbh=DBI->connect。
  • @Kraken:那不是真正的配置文件,它只是设置数据常量。您可以使用use constant 从那里设置 DSN、用户名和密码,但您需要能够在一天中反复检查数据库连接并根据需要重新连接。最好使用适当的 Perl 模块和 Exporter 将值传递回主程序。
猜你喜欢
  • 2015-10-31
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多