У меня есть простой скрипт Perl, который прослушивает сетевой порт, принимает данные и записывает данные в базу данных с использованием DBD :: ODBC. Это выглядит примерно так:Обработка критических ошибок 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: [email protected]");
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.
Если бы я хотел сценарий быть resiliant к такого рода неудачи, либо просто ждет в течение заданного периода времени и увидев, что если база данных снова проснулась или отбросила полученные данные и вытащила больше данных из сокета, что было бы лучшим способом обойти это? Вызывает ли вышеупомянутая ошибка, что $ dbh заканчивается нежелательным и нуждается в повторной инициализации?
Если бы я хотел, чтобы не выйти из цикла, а просто подождать некоторое время для DB, чтобы вернуться, прежде чем продолжить, я мог бы просто позвонить 'спать' немного? Кроме того, '' msg' автоматически заполняется командой 'execute'? – growse
Если вы не хотите выйти, вам нужно будет создать новое соединение. Замените 'break' новым вызовом' DBI-> connect() '. Вам придется перестроить свой цикл для поддержки повторных попыток, чтобы вы не отбрасывали сетевые сообщения. – saarp
На самом деле я не беспокоюсь о снижении сетевого трафика, хотя я ценю эту мысль. Я пойду и посмотрю, что я могу найти. – growse