Autor |
Beitrag |
Nico B.
      
Beiträge: 45
Win XP
Delphi 2006 Prof.
|
Verfasst: Do 08.12.11 16:23
Hallo Leute,
ich brauche dringend Hilfe bei einem etwas komplexeren Problem.
Ich habe eine ADOConnection die eine Verbindung zu einer Datenbank aufbaut, die auf einem anderen PC im Netzwerk liegt.
Ich möchte nun dafür sorge tragen, dass diese Verbindung immer besteht, bzw. bei einem Verbindungsabbruch so bald wie möglich wieder aufgebaut wird.
Ich habe das schon mit dem OnDisconnect-Ereignis und dem AfterDisconnect-Ereignis der ADOConnection versucht, leider hatte ich nicht das Gefühl, dass eins der Ereignisse ausgelöst hat, als ich bei meinem PC das Netzwerkkabel rausgezogen habe.
Habt ihr andere Ideen?
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Do 08.12.11 16:40
Kann es sein, dass Du versuchst, ein Hardwareproblem softwaretechnisch zu lösen? Das geht in 99% der Fälle schief.
Ansonsten, überprüfe jedesmal, bevor Du die Connection verwendest, ob sie noch besteht (z.B. Testkommando schicken und schauen obs klappt). Oder geh einen Schritt weiter und bau die Connection generell erst dann auf, wenn Du sie benötigst. Und hinterher bau sie wieder ab. Wenn die DB Connectionpooling kann, ist das normalerweise problemlos möglich und sollte die Performance auch nicht stark beeinträchtigen.
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
Nico B. 
      
Beiträge: 45
Win XP
Delphi 2006 Prof.
|
Verfasst: Fr 09.12.11 08:44
Hallo Nersgatt,
mein Problem ist, dass dieses Programm ständig vor sich her läuft ohne das jemand danach schaut.
In bestimmten Zeitabständen führt das Programm verschiedene Datenbankabfragen aus.
Mein Problem ist nun, dass es erst bemerkt wird, wenn es zu spät ist, dass die Datenbankverbindung getrennt wurde.
Lieber wäre mir mein Programm merkt das selbst und probiert wiederrum selbständig den erneuten Verbindungsaufbau.
Gibt es eine bestimmte Exception die bei fehlender Datenbankverbindung ausgelöst wird?
Dann könnte ich die Fehlerbehandlung vielleicht so auslösen.
Ich habe einfach noch keinen richtig guten Ansatz für die Lösung dieses Problems.
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 09.12.11 08:54
Wenn Du keine größeren kollabierenden Oberflächen hast langt je bei den Aktion ein
Try
except
Reconnect;
JobAufWiedervorlageIn1Sekunde
end
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
Nico B. 
      
Beiträge: 45
Win XP
Delphi 2006 Prof.
|
Verfasst: Fr 09.12.11 09:12
Hallo Bummi,
ich habe zur Exceptionbehandlung eine Prozedur für das OnException-Ereignis der Application geschrieben.
Nun würde ich natürlich deinen Lösungsansatz gern in dieser Prozedur umsetzen.
Gibt es eine Möglichkeit herauszufinden, ob die Exception ausgelöst wurde, weil die ADOConnection getrennt wurde?
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Fr 09.12.11 10:30
Wenn du einen Dienst oder ähnliches hast, was 24/7 läuft, dann solltest du die Verbindung nicht einmalig aufbauen und dann einfach immer wieder verwenden, sondern wie Nersgatt vorgeschlagen hat jedes Mal die Verbindung aufbauen, wenn du sie brauchst.
Da kannst du dann ja 10x (oder so) versuchen, die Verbindung aufzubauen, bevor du kapitulierst.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| I := 0; repeat try ADOConn.Connected := True;
Sleep(1000); Inc(I) except end; until (ADOConn.Connected or I > 10);
if (not ADOConn.Connected) raise Exception.Create('Verbindung konnte nicht hergestellt werden.'); |
|
|
Nico B. 
      
Beiträge: 45
Win XP
Delphi 2006 Prof.
|
Verfasst: Fr 09.12.11 10:42
Hallo baka0815,
ok einverstanden.
Dann bleibt für mich allerdings noch ein Problem, was ich mir nicht so recht erklären kann.
Ich habe nun mit einem Timer regelmäßig die ADOConnection überprüft.
Delphi-Quelltext 1: 2: 3: 4: 5:
| if ADOConnection.Connected then else |
Für mich war die einfachste Testmöglichkeit, die Verbindung aufzubauen und anschließend das Netzwerkkabel aus meinem PC zu ziehen. Nur leider erkennt mein Programm daraufhin nicht, dass die ADOConnection nicht mehr verbunden sein kann.
Woran liegt das?
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 09.12.11 11:01
Weil das Flag nur bei einem Zugriff gesetzt wird
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Function IsConnected(AC:TAdoConnection):Boolean; var sl:TStringList; begin sl:=TStringList.Create; Result := AC.Connected; try try if Result then AC.GetTableNames(sl); Except Result := false; end; finally sl.Free; end; end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
baka0815
      
Beiträge: 489
Erhaltene Danke: 14
Win 10, Win 8, Debian GNU/Linux
Delphi 10.1 Berlin, Java, C#
|
Verfasst: Fr 09.12.11 11:02
Die Connected-Eigenschaft ist nur ein Flag das gesetzt wird. Wenn du Connected abfragst weißt du nur, dass die Verbindung (mal) aufgebaut wurde. Ob die Verbindung tatsächlich besteht erfährst du dann erst beim wirklichen Benutzen der Verbindung.
Ist wie bei allen asynchronen Aufrufen.
Wenn du eine Verbindung zu Server aufbaust ist die Verbindung hergestellt. Wenn du dann auf den Server zugreifst, kann in der Zwischenzeit die Verbindung abgebrochen sein.
Daher hilft es auch leider nicht wirklich ein "Test-SQL" zu schicken. Dieses könnte funktionieren, aber der tatsächliche Aufruf danach dann nicht mehr.
|
|
Nico B. 
      
Beiträge: 45
Win XP
Delphi 2006 Prof.
|
Verfasst: Fr 09.12.11 14:24
Hallo Leute,
vielen Dank für eure Erklärungen und Lösungsvorschläge.
Damit wird mir jetzt natürlich einiges klar.
Ich habe Bummis Lösungsvorschlag umgesetzt.
Und siehe da - es funktioniert.
Nun brauche ich mir keine Sorgen mehr um meine Datenbankverbindungen machen.
Problem gelöst!
Danke!!!
|
|