PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: "Jason L dot Froebe" <jason at froebe dot net>
Subject: perl DBI::Sybase - How to reconnect through err_handler
Date: Nov 7 2006 11:32PM

I'm writing an application with a business requirement of reconnecting
a dead db connection to Sybase through the syb_err_handler() error
handler routine.

In the past, I would just run $dbh->DBDEAD() just prior to running the
queries. If the connection was dead, I would just reconnect and run the
query (plus any initialization db routines).

The syb_err_hander() can easily catch a dead connection but calling
$dbh->connect() in the error handler fails

$ ./test_sybase

ERROR: Connection dropped
ct_config(CS_SET, CS_LOGIN_TIMEOUT) failed at /usr/lib64/perl5/site_pe
+rl/5.8.8/x86_64-linux-thread-multi/DBD/Sybase.pm line 94.
ct_config(CS_SET, CS_TIMEOUT) failed at /usr/lib64/perl5/site_perl/5.8
+.8/x86_64-linux-thread-multi/DBD/Sybase.pm line 94.
ct_con_alloc failed at /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-t
+hread-multi/DBD/Sybase.pm line 94.
ERROR: unable to connect to SISDBA

Has anyone done this?

===============
#!/usr/bin/perl

use strict;
use warnings;

use lib "/home/jfroebe/lib";

use DBI;
use File::Basename;

our $SYBDBA_login = 'login';
our $SYBDBA_password = 'password';

our $dbh = connect_dbms();

sub report_err {
        my $msg = shift;
        my $type = shift;

        if ($type eq 'error') {
                print "ERROR: $msg\n";
        } else {
                print "MSG: $msg\n";
        }
}

sub syb_err_handler {
    my($err, $sev, $state, $line, $server, $proc, $msg, $sql, $err_typ
+e) = @_;

    my %ignore_errors = map { $_, 1 } (6, 183, 208, 2056, 2057, 14024,
+ 17001);

        if ($err == 151 || $err == 50 || $err == 60) {
                report_err("Connection dropped", "error");

                for (my $attempt = 0; $attempt < 10; $attempt++) {
                        if ($dbh = connect_dbms()) {
                                report_err("Reconnected", "error");
                                return 0;
                        }

                        sleep 2;
                }

                return 1;
    } elsif ($err == 63 || ($err == 4 && $sev == 5) ) {
        report_err("Connection timed out", "error");
        return 1;
    } elsif ($ignore_errors{$err}) {
        # ignore
        return 0;
    }

    print "error: $err, $sev, $state : $msg\n";
    return 1;
}

sub connect_dbms {
    my $script = basename($0);

    if ($dbh = DBI->connect("dbi:Sybase:server=SISDBA;loginTimeout=10;
+timeout=30;scriptName=$script;encryptPassword=1;tdsLevel=CS_TDS_50;ch
+arset=iso_1", $SYBDBA_login, $SYBDBA_password, { PrintError => 0, Rai
+seError => 0, syb_err_handler => \&syb_err_handler } )) {
        return $dbh;
    }

    report_err("unable to connect to SISDBA", "error");
    return;
}

sub syb_loop {
        my $query = "exec sp_helpdb";

        for (my $i = 0; $i < 10000; $i++) {
                my $array_ref = $dbh->selectall_arrayref($query);
        }
}

syb_loop();


Jason L. Froebe

He was the sort of person who stood on mountaintops during thunderstorms in wet copper armour shouting "All the Gods are bastards." --- Terry Pratchett 

WebBlog http://jfroebe.livejournal.com
Tech log http://www.froebe.net/blog

TeamSybase (http://www.teamsybase.com)
ISUG member (http://www.isug.com)
Chicago Sybase Tools User Group (http://www.cpbug.com)