Hans: dbi SQLite errors unterdrücken

Hallo,

habe ein Perl-Script das mit einer sqlite db arbeitet. Funktioniert alles tadellos, nur wenn ich Tests mit massiv parallelen Aufrufen mache erhalte ich manchmal die Rückmeldung von SQLite dass die DB gelockt ist.
Mein Script wertet den Rückgabewert der SQLite Operation aus und führt das SQL noch einmal bis zu einem Grenzwert aus wenn Fehler festgestellt wurden. Den Error erhalte ich aber trotzdem auf der Console:
Error: database is locked

Den Connect Anfang des Scriptes mache ich so:

$dbh = DBI->connect("dbi:SQLite:dbname=meinedb.db", "", "", {
        PrintError => 0,
        PrintWarn => 0,
        RaiseError => 0,
        AutoCommit => 1
  });

Queries dann später per:

$dbh->do("insert into....;");
oder
$res = $dbh->selectall_arrayref("select foo from bar;");

Was kann ich noch tun um den Error zu unterdrücken? Ich logge diesen schon mit, kann ihn aber als Ausgabe die der User sieht absolut nicht gebrauchen.
Innerhalb des Scriptes habe ich auch ein "no warnings;" oder als Shebangzeile ein "#!/usr/bin/perl -X" probiert, hat aber nichts weiter geholfen.

Danke,
Hans

  1. Was kann ich noch tun um den Error zu unterdrücken?

    Falsche Frage. Du willst immer alle Fehler erzeugen (lassen), und dann selektiv behandeln oder ignorieren. Das Konzept nennt sich Exceptionhandling, siehe Kapitel 13 PBP und Try::Tiny.

      
        use 5.010;  
        use DBI qw();  
        use Try::Tiny;  
      
        my $dbh = DBI->connect("dbi:SQLite:dbname=meinedb.db", "", "", {  
            RaiseError => 1,  
            AutoCommit => 1,  
        });  
      
        ⋮  
      
        try {  
            $dbh->do();  
        } catch {  
            when /database is locked/ {}    # ignore  
            default { die $_ }              # rethrow  
        };  
    
    
    1. Hallo,

      ahh, danke. Habs installiert und umgesetzt aber die Zeile erscheint trotzdem noch.

      use 5.010;
          use DBI qw();
          use Try::Tiny;

      my $dbh = DBI->connect("dbi:SQLite:dbname=meinedb.db", "", "", {
              RaiseError => 1,
              AutoCommit => 1,
          });

      try {
              $dbh->do(…);
          } catch {
              when /database is locked/ {}    # ignore
              default { die $_ }              # rethrow
          };

        
      ich glaub ich muss dir mal die subroutine zeigen. ich find nicht was da falsch sein sollte. Selbst wenn ich im CatchBereich nur den default zum ignorieren angebe sehe ich die Meldung.  
      Den connect mache ich genauso wie du oben. Diese sub bekommt ein sql als funktionsparameter übergeben:  
        
      ~~~perl
      sub sqliteselect  
      {  
              $errorcount=0;  
              do  
              {  
                      $errorcount++;  
                      try{  
                              $res = $dbh->selectall_arrayref($_[0]);  
                      } catch {  
                              default { }  
                      };  
        
              }while ($dbh->err() > 0 && $errorcount <= 10);  
              if($errorcount>10){  
                   bla;  
      	     bla;  
              }  
              else  
              {  
                      return $res;  
              }  
      }
      

      Siehst du was?

      Danke,
      Hans

      1. Hallo,

        ich find nicht was da falsch sein sollte.

        ach unsinn, es war der connect selbst und nicht die ausführung des sql ;)

        Danke,
        Hans