正常处理Perl关键DBD :: ODBC错误

时间:2011-12-28 23:57:32

标签: perl exception-handling odbc

我有一个简单的Perl脚本,它侦听网络端口,接受数据并使用DBD :: ODBC将数据写入数据库。它看起来有点像这样:

#!/usr/bin/perl
my $dbh = DBI->connect('dbi:ODBC:SqlProd',"yay","ooo",{AutoCommit => 0}) || die "Couldn't connect to db";
my $sth = $dbh->prepare("insert into table some stuff");

$sock = IO::Socket::INET->new(LocalPort => '1234', Proto => 'udp')||die("Socket: $@");
do {
    $sock->recv($buf, $MAXLEN);

    /*parse some data here*/
    /*bind some parameters to $sth here*/

    my $rv = $sth->execute() || warn logit('warning', "Error inserting to db: $! $msg");
    $dbh->commit() || warn logit('err',"Error committing db transaction: $! $msg");

}while(1);

这虽然有点粗糙,但运作得相当好。但是,由于未知原因,数据库崩溃,脚本崩溃,如下所示:

DBD::ODBC::st execute failed: [unixODBC][FreeTDS][SQL Server]Write to the server failed     (SQL-08S01) at /usr/local/bin/haproxy-syslog line 117.
0 at /usr/local/bin/haproxy-syslog line 117.
DBD::ODBC::db commit failed: [unixODBC][FreeTDS][SQL Server]Could not perform COMMIT or     ROLLBACK (SQL-HY000) at /usr/local/bin/haproxy-syslog line 118.
Error committing db transaction: Connection reset by peer 
DBD::ODBC::db DESTROY failed: [unixODBC][FreeTDS][SQL Server]Could not perform COMMIT or ROLLBACK (SQL-HY000) during global destruction.

如果我希望脚本能够恢复这种类型的故障,可以等待一段时间,看看数据库是否再次唤醒,或者丢弃收到的数据并从套接字中提取更多数据,什么是最好的方式呢?上述错误是否意味着$ dbh最终成为垃圾并且需要重新初始化?

1 个答案:

答案 0 :(得分:1)

问题是由于即使execute()失败,您仍然在调用commit()。由于没有连接,因此无法向DB发送提交调用。此外,您似乎已启用AutoCommit,以便DB在DESTROY调用中处理连接时尝试关闭所有打开的事务。

你可以尝试这样的事情(原谅我生锈的perl):

do {
    $sock->recv($buf, $MAXLEN);

    # parse some data here
    # bind some parameters to $sth here

    my $rv = $sth->execute() || warn logit('warning', "Error inserting to db: $! $msg");
    if ($msg ~= /connection reset/i)
    {
        warn logit('warning', "Connection disconnected.");
        $sth->disconnect();
        break; # exit while
    }
    $dbh->commit() || warn logit('err',"Error committing db transaction: $! $msg");

}while(1);