AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Abgebrochene ADOConnection wiederherstellen
Thema durchsuchen
Ansicht
Themen-Optionen

Abgebrochene ADOConnection wiederherstellen

Offene Frage von "Iwo Asnet"
Ein Thema von Nico B. · begonnen am 4. Jul 2012 · letzter Beitrag vom 5. Jul 2012
Antwort Antwort
Seite 1 von 2  1 2      
Nico B.

Registriert seit: 16. Okt 2006
Ort: Riesa
67 Beiträge
 
Delphi XE7 Enterprise
 
#1

Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 08:06
Datenbank: MS Access • Version: 5? • Zugriff über: ADO
Hallo alle miteinander,

ich habe ein Problem mit einer ADOConnection und brauche eure Hilfe.

Ich habe eine Datenbankverbindung, die ab und an abbricht, weil mein Netzwerk zusammenbricht.
Nun habe ich schon verschiedene Möglichkeiten probiert, um die Verbindung nach dem Zusammenbruch wiederherzustellen.

Aktuell ist dies mein Quellcode zum Wiederaufbau der Verbindung:
Delphi-Quellcode:
//Globale Variable
var
  ADOC_CNC: TADOConnection;

//Funktion zum Test der Verbindung
function Test_CNCDB: boolean;
var
  slHilf: TStringList;
begin
  slHilf:=TStringList.Create;
  Result:=ADOC_CNC.Connected;
  try
    try
      if Result
        then
          ADOC_CNC.GetTableNames(slHilf);
    except
      Result:=false;
    end;
  finally
    slHilf.Free;
  end;
end;

//Funktion zum Herstellen der Verbindung
function Open_CNCDB: boolean;
begin
  Result:=true;
  try
    if Test_CNCDB
      then
        begin
          if Close_CNCDB
            then
              begin
                ADOC_CNC.ConnectionString:='...';
                ADOC_CNC.LoginPromt:=false;
              end
            else
              begin
                //Fehler beim Trennen der Verbindung
              end
        end
      else
        begin
          ADOC_CNC.ConnectionString:='...';
          ADOC_CNC.LoginPromt:=false;
        end;
    ADOC_CNC.Open;
  except
    Result:=false;
  end;
end;

//Funktion zum Trennen der Verbindung
function Close_CNCDB:boolean;
begin
  Result:=true;
  try
    ADOC_CNC.Close;
  except
    Result:=false;
  end;
end;

//Nun das Wiederherstellen der Verbindung im eigentlichen Programm
if not Test_CNCDB
  then
    begin
      Close_CNCDB;
      if Open_CNCDB
        then
          //Wiederaufbau der Verbindung erfolgreich
        else
          //Verbindung konnte nicht wieder hergestellt werden
    end;
Habt ihr ne Idee, warum der Wiederaufbau der Verbindung nie klappt?
Ich probiere seit Tagen an diesem Code rum und bekomme es einfach nicht hin.
Nico Bäger
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 09:00
Frage: greifst du wirklich auf eine MS Access Datenbank über das Netzwerk (also eine MDB-Datei auf einem freigebenen Verzeichis) zu?
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#3

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 09:33
Frage: greifst du wirklich auf eine MS Access Datenbank über das Netzwerk (also eine MDB-Datei auf einem freigebenen Verzeichis) zu?
Der Einwand ist berechtigt, beantwortet aber nicht die ursprüngliche Frage.

Ich mache es immer so:
Delphi-Quellcode:
Procedure DoDatabaseStuff;
  Procedure _InnerDoDatabaseStuff;
  Begin
    // Lesen, beschreiben whatever der DB.
  End;

Begin
  Try
    _InnerDoDatabaseStuff;
  Except
    Reconnect;
    _InnerDoDatabaseStuff;
  End
End;
Ich gehe davon aus, das die Verbindung ok ist ('happy path'). Wenn nicht, baue ich die Verbindung neu auf und versuche mein Glück nochmal.

Natürlich sollte man die Exception auswerten und nur bei Verbindungsproblemen neu verbinden, klar.

Bei Neuaufbau der Verbindung kann man
* Eine Meldung aufpoppen lassen
* Es mehrmals versuchen
* Durch eine eigene Exception den Programmfluss kontrolliert unterbrechen.
  Mit Zitat antworten Zitat
Nico B.

Registriert seit: 16. Okt 2006
Ort: Riesa
67 Beiträge
 
Delphi XE7 Enterprise
 
#4

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 09:50
Hallo ihr beiden,

also erst mal zu sx2008:
Ja, ich greife auf eine mdb-Datei auf einem freigegebenen Verzeichnis zu (Data Source=\\123.123.123.132\ordner\datenbank.mdb). Aber wo liegt hier das Problem?

@Furtbichler:
Ich denke, wie man nun mitbekommt, dass ein reconnect notwendig ist, ist in meinem Fall erstmal zweitrangig. Mich interessiert eher, wie man den reconnect richtig macht, denn meiner funktioniert irgendwie nicht.
Ich mache den reconnect folgendermaßen:
1. Testen, ob die Verbindung noch besteht (dazu nehme ich meine Funktion Test_CNCDB)
=> 2. wenn nicht, dann Verbindung trennen (dazu nehme ich meine Funktion Close_CNCDB)
und anschließend Verbindung neu aufbauen (dazu nehme ich meine Funktion Open_CNCDB)
Nico Bäger
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#5

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 09:58
1. Access über Netzlaufwerk: Schlecht, wegen Mehrbenutzerbetrieb usw. GANZ Schlect!
2. Wieso prüfen, ob die Verbindung besteht? Bau sie im Fehlerfall neu auf. Du könntest die Connection auch verwerfen und eine neue instantiieren.
Delphi-Quellcode:
MyADOConnection.Connected := False;
MyADOConnection.Connected := True;
Reicht doch, oder? Wenn das wider Erwarten nicht funktioniert, dann eben so:
Delphi-Quellcode:
MyADOConnection.Free;
MyADOConnection := TADOConnection.Create(Nil);
MyADOConnection.ConnectionString := MyConnectionString;
MyADOConnection.Connected := True;
Ich finde das simpel, viel simpler als deinen Ansatz.
  Mit Zitat antworten Zitat
Nico B.

Registriert seit: 16. Okt 2006
Ort: Riesa
67 Beiträge
 
Delphi XE7 Enterprise
 
#6

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 14:41
Da bin ich wieder.
Ich wollte soeben probieren, ob es so einfach geht.
Habe dazu ein Testprogramm geschrieben.
Über einen Button kann ich die Verbindung herstellen
und über einen zweiten Button kann ich die Verbindung trennen.
Mit dem dritten Button kann ich die Verbindung testen.

So weit so gut.

Nun stelle ich die Verbindung her. -> Klappt.
Anschließend teste ich den Verbindungszustand. -> Klappt.
Dann ziehe ich das Netzwerkkabel von meinem Rechner.
-> Nun dürfte die Verbindung nicht mehr bestehen.
Ich teste also wieder den Verbindungszustand. -> Ergebnis: Verbindung besteht.
Das kann aber nicht sein!!!

Den Test der Verbindung habe ich über 3 verschiedene Wege probiert:
1. Über die Eigenschaft Connected der ADOConnection
Delphi-Quellcode:
if ADOC_CNC.Connected
  then //Verbindung besteht
2. Über eine Abfrage des Tabellenkopfes
Delphi-Quellcode:
try
  ADOQ_CNC.GetTableNames(Hilfsstringliste);
except
  //Verbindung unterbrochen
end;
3. Über eine Abfrage des Tabelleninhalts

Alle 3 Möglichkeiten funktionieren wie bei einer bestehenden Datenbankverbindung.
Warum?
Beziehungsweise was viel wichtiger ist, wie kann ich die Verbindung besser testen?
Nico Bäger
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#7

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 15:34
Die Jetengine cached.
Du könntest eine Thread starten der eine eiegen Connection erzeugt, aufbaut und im OnTerminate den "Status" abliefert.


nur als Beispiel ...
Delphi-Quellcode:
unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DB, ADODB,ActiveX;

type
   TCheckThread=Class(TThread)
     private
     FConn:TAdoconnection;
     FErr:Boolean;
     protected
     Procedure Execute;override;
     Destructor Destroy; override;
     public
     Property Error:Boolean read FErr;
     Constructor Create(Acon:TAdoConnection);

   End;

  TForm5 = class(TForm)
    ADOConnection1: TADOConnection;
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure MyOnTermiante(Sender: TObject);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form5: TForm5;

implementation
uses JRO_TLB,ADODB_TLB;

{$R *.dfm}

procedure TForm5.MyOnTermiante(Sender: TObject);
begin
   if TCheckThread(Sender).Error then Showmessage('Fehler') else Showmessage('OK')

end;


procedure TForm5.Button1Click(Sender: TObject);
begin
  With TCheckThread.create(AdoConnection1) do OnTerminate := MyOnTermiante;
end;


{ TCheckThread }

constructor TCheckThread.Create(Acon: TAdoConnection);
begin
  inherited Create(false);
  CoInitialize(nil);
  FConn := Acon;
  FreeOnTerminate := true;

end;

destructor TCheckThread.Destroy;
begin
   CoUninitialize;
  inherited;
end;

procedure TCheckThread.Execute;
begin
  inherited;

  With TAdoConnection.Create(nil) do
    try
       ConnectionString:= Fconn.ConnectionString;
        try
           ConnectionTimeOut := 2;
           CommandTimeOut := 2;
           connected := true;
         except
          FErr := true;
        end;

    finally
      Free;
    end;

end;

end.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)

Geändert von Bummi ( 4. Jul 2012 um 15:49 Uhr)
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#8

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 4. Jul 2012, 16:20
So eine Verbindung bekommt vom gezogenen Kabel nichts mit.
Stell Dir vor, Du machst das im Firmennetz und die Datei liegt auf einem Server in Honolulu und der dortige Admin stolpert über das Netzwerkkabel (klar, und wird gefeuert, der Depp).

Auf deinem PC ist die Welt so lange in Ordnung, bis Du versuchst, mit der Verbindung aktiv zu arbeiten. Bis dahin sagt die dir 'Alles in Butter, als mich hat noch niemand getrennt'.

Du kannst natürlich vor jeder Aktion prüfen, ob eine Verbindung besteht. Aber dazu musst Du irgend etwas mit der Verbindung anstellen. Einige Treiber machen das, indem Sie ein 'SELECT 1' schicken. Dieser Befehl wird im Server (den Du nun mal nicht hast, aber egal) verarbeitet und dann wird eine Tabelle bestehend aus einer Zeile und einer Spalte als Ergebnis geschickt. Wenn das klappt, ist die Verbindung ok. Das 'SELECT 1' ist deshalb beliebt, weil es kaum Last erzeugt.

Bei ACCESS müsste man das probieren, welcher Befehl schnell geht und trotzdem die Verbindung aktiv auffordert, sich mit der MDB-Datei zu beschäftigen.

Allerdings würde ich es einfach drauf ankommen lassen und bei einem Fehler die Verbindung neu aufbauen.

Alternativ kannst Du dir Gedanken über das 'Briefcase' Modell machen, bei der bewusst mit der Tatsache gearbeitet wird, das der Client nicht ständig Zugriff auf die Zentrale hat (Briefcase = Aktenkoffer => Außendienstmitarbeiter).
  Mit Zitat antworten Zitat
Nico B.

Registriert seit: 16. Okt 2006
Ort: Riesa
67 Beiträge
 
Delphi XE7 Enterprise
 
#9

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 5. Jul 2012, 08:40
Hallo Leute,

ich habe jetzt eine Lösung für mein Problem gefunden.
Leider weiß ich zwar nicht wie man in meinem Fall einen Verbindungsausfall richtig erkennt, aber das Problem habe ich ein wenig umgangen. Das "SELECT 1" oder auch eine etwas tiefergehende Abfrage (bspw. nach dem ersten oder letzten Element einer bestimmten Tabelle) wie es mir von Iwo Asnet vorgeschlagen wurde, hat leider nicht funktioniert.

Hier mein Lösungsweg:
1. Ich gehe davon aus, dass die Verbindung zu meiner Datenbank immer besteht.
2. Über eine AppException fange ich alle Fehler meines Programms ab.
3. Entsteht der Fehler bei einer Datenbankabfrage versuche ich automatisch die Verbindung neu aufzubauen. Dazu trenne ich die Verbindung und starte anschließend einen TTimer.
4. Bei jedem Start des Timerevents versuche ich nun die Verbindung wieder aufzubauen.

Hier ein Teil des Quellcodes:
Delphi-Quellcode:
//im AppException-Event des Programms...
ADOC_CNC.Connected:=false;
Timer1.Enabled:=true;

//nun das Timer-Event...
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //Verbindung neu aufbauen
  try
    ADOC_CNC.Connected:=true;
    if ADOC_CNC.Connected
      then
        Timer1.Enabled:=false;
  except
    //Verbindungsaufbau gescheitert -> neuer Versuch im nächsten Event
  end;
end;
Damit ist zwar nicht alles geklärt, aber ich kann damit zumindest erst mal weiter.
Danke euch allen!
Nico Bäger
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#10

AW: Abgebrochene ADOConnection wiederherstellen

  Alt 5. Jul 2012, 08:52
Delphi-Quellcode:
Function ConnectionIsValid (aConnection : TADOConnection);
Begin
  Try
    aConnection.Execute('SELECT 1');
    Result := True
  Except
    Result := False
  End
End;
Das sollte funktionieren.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz