Noch einmal die Grundlage: Jede Nacht läuft ein Backup mit Veeam, das die gesamte VMWare-Maschine sichert. Ausnahmen sind nicht zugelassen (t. B. die dbf raus lassen). Der Hinweis ist hier nicht nötig, denn das machen die Admins nicht. Auch ein Unterbrechen des Programms zum zeitraum des Backups ist nicht möglich, das muß zwingend 7/24 durchlaufen. Das Problem: Wenn Veeam anspringt, dann sind die Dateien jeweils für kurze Zeit nicht sichtbar. Wenn ich nun in genau dem Augenblich eine Datenbankoperation durchführen möchte, dann kommt logischerweise ein Laufzeitfehler. Andererseits macht Veeam das anscheinend so, das der Dateihandle nicht gebrochen wird. Denn nach der Freigabe sind z. B. Grafiken, die zur Bearbeitung geöffnet sind, weiterhin bearbeitbar.
Meine Idee war nun, direkt vor jeder Datenbankoperation kurz zu kontrollieren, ob die dbf sichtbar ist. Dazu habe ich diese Funktion geschrieben:
Code: Alles auswählen
FUNCTION istDbfNochDa
LOCAL bOldError := NIL
LOCAL lReturn := .T.
bOldError := ErrorBlock({|e| BREAK(e)}) // Eigenen Errorhandler einbauen, greift im Falle des RECOVER
DO WHILE .T. // So lange laufen lassen, bis ein kontrolliertes "Exit" kommt
BEGIN SEQUENCE // Eigene Laufzeitfehler-Behandlung starten
knx->(DbGoTo(1)) // Einfach zur Überprüfung auf den 1. Satz springen
RECOVER // Was tun bei einem Laufzeitfehler
lReturn := .F.
END SEQUENCE
IF lReturn == .T. // Wenn Sperre erfolgreich ...
Exit // ... raus aus der Schleife
ELSE // ... sonst
lReturn := .T. // ... Kontrollvariable zurücksetzen für den nächsten Durchlauf
ENDIF
Sleep(1000) // 1000/100 = 10 Sekunden warten. Lt. IsAppRunning() müsste das genügen
ENDDO
ErrorBlock(bOldError) // Original-Fehler-Codeblock wiederherstellen
RETURN NIL
Das Problem: Die Schleife hängt einfach nach dem Backup (da ich immer die jeweils kontrolierten Daten inkl. Uhrzeit und Datum ausgebe, kann ich den Zeitpunkt sehr genau eingrenzen). Weil ich keine Ahnung habe warum und wo, habe ich da gestern eine Kontrollstruktur eingebaut, die zusätzlich einen Schleifenzähler und den Wert von lReturn ausgibt. Heute früh stand lReturn auf .F. und der Zähler auf über 2.500 Durchläufen. Da die Varable IMMER auf .T. zurückgesetzt wird, muß der DbGoTo(1) nach dem Veeam-Backup also grundsätzlich scheitern. Warum sonst sollte der sonst in den RECOVER springen?
Oder habe ich da einen Denkfehler drin? Oder einen weiteren Fehler in der Sequence-Struktur?
Die Alternative für mich wäre, das ich im Fall, das lReturn mir ein .F. zurückgibt, ich einfach alle dbf schließe und nach 10 Sekunden neu öffne. 10 Sekunden sind vollkommen ausreichend, da die Veeam-Sperre niemals länger dauert. Aber das ist natürlich die ganz grobe Keule, die ich ganz gerne vermeiden möchte.
Jan