Speichern eines Datensatzes, merkwürdiger Fehler

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Speichern eines Datensatzes, merkwürdiger Fehler

Beitrag von Lewi »

Hi Folks,
ich habe bei einem Kunden folgendes Problem:

Ein Anwender ändert Daten innerhalb einer Maske. Beim Speichern dieser Änderungen werden die Änderungen in einem anderen Datensatz abgespeichert. Das Problem ist, dass dieser Fehler in der Vergangenheit nur hin und wieder aufgetreten ist und ich keine Anhaltspunkte habe, wo das Problem liegt.

Interessanter Weise tritt dieses Problem nur beim Kunden auf und ist nicht reproduzierbar. Wenn ich die kompletten Daten-Dateien auf mein Netzwerk einspiele und die Änderungen durchführe, wie sie der Kunde macht, tritt dieses Problem nicht auf.

Um den Grund der Fehlerursache zu kommen, habe ich in der Write()-Routine folgenden Code eingebaut:

Code: Alles auswählen


IF !::lAppend

            // Datensatz-Nr. des angezeigten Datensatzes stimmt nicht mit Datensatzzeiger überein
	IF ::nActEditRec <> oPage:server:RecNo()
		AppInfoBox("Fehlercode (1), speichern nicht möglich")
		Return (.F.)
	ENDIF

   // Der Inhalt des Get-Controls stimmt nicht mit dem Inhalt des 
   // Datenbankfeldes überein, wobei das Get-Control 
   // nicht editiert werden kann!
	IF oPage:sleNr:GetValue() <> oPage:server:Fieldget(1)
		AppInfoBox("Fehlercode (2), speichern nicht möglich")
		Return (.F.)
	ENDIF

ENDIF
Der Kunde meldete mir nun den „Fehlercode (2)“. Das finde ich „überraschend“, da ja wohl die Datensatz-NR aus ::nActEditRec, die bei Eintritt in den Editzustand der Maske automatisch dieser Member-Variable zugewiesen wird, mit dem aktuellem Datensatzzeiger übereinstimmt.

Wieso dann der Inhalt des bezeichneten Get-Feldes nicht mit dem Inhalt des Feldes übereinstimmt, wenn die erste Bedingung nicht zutrifft, bleibt mit schleierhaft. Zumal dieses Feld nur beide Neu-Anlage eines Datensatz editiert werden kann und ansonsten gesperrt ist.

Die Vermutung, dass der Datensatzzeiger im Laufe des Editierens woanders hin gesetzt wird, bin ich auch nachgegangen. Allerdings müsste dann die aktuelle Satz-Nr. nicht mit der Datensatz-Nr. der Member-Variablen übereinstimmen.

Ich habe den Verdacht, dass das Problem im Zusammenhang mit CIRIX steht. Die Anwendung wird in einer Außenstelle des Kunden unter CITRIX genutzt. Die Außenstelle ist im Rahmen eines WLAN´s über Internet mit der Zentrale verbunden. Der entsprechende CTRIX-Server steht auch in der Zentrale.

Die Anwendung wurde mit xbase 1.82 erstellt.

Ich bin auch der Frage nachgegangen, ob die zur Datenbank zugehörige CDX-Index-Datei defekt ist. Tests haben aber ergeben, dass dies nicht die Fehlerursache sein kann. Ferner werden alle Speicherungsvorgänge mit einem Commit() und Skip(0) abgeschlossen.

Hat jemand eine Idee, wo das Problem liegen könnte?


Beste Grüße,
Olaf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Beitrag von brandelh »

Hi,

sicherlich nicht am Citrix, da Citrix (Terminalserver) nichts anderes macht als auf die Bildschirmausgaben des Programmes auf dem CitrixServer (normales Windows) über die Fernleitung (oder nur LAN) auf dem Client anzuzeigen. Im Prinzip wie VNC ... für dein Programm ist es genau das gleiche ob du dich direkt an dem PC angemeldet hast und davor sitzt.

Natürlich kann die Kiste selbst das Problem sein ...
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Beitrag von Tom »

Hallo, Olaf.

Also liefern GetValue() (was macht diese Methode?) und FieldGet() verschiedene Ergebnisse zurück. Das kann m.E. einige Ursachen haben, zum Beispiel Fehler in dieser (eigenen?) Methode "GetValue" - oder Zeichensatztransformationsfehler. Enthält das fragliche Feld im Fehlerfall Umlaute oder ähnliches? Schonmal die Werte innerhalb dieser Abfrage protokolliert oder in einem Debug-Fenster ausgegeben?
Herzlich,
Tom
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Speichern eines Datensatzes, merkwürdiger Fehler

Beitrag von AUGE_OHR »

hi,
Lewi hat geschrieben: Interessanter Weise tritt dieses Problem nur beim Kunden auf und ist nicht reproduzierbar.
ist das nicht immer so ...

ok mal im Ernst, wenn der Kunde mehrer PC´s hat und das Problem
nur auf einem PC bei ihm auftaucht dann gibt es nur eins : Vergiss es !!!

Was ich damit meine ist die Tatsache das deine Application auf mehreren
PC´s funktioniert aber auf der einen Kiste nicht. Es ist also offensichtlich
ein Problem mit dem PC ob Hard- oder mit anderer Software. (Virus ?)

Zur Hardware kann ich nur sagen : RAM insbesondere wenn der PC > 3
Jahre alt ist. Ich hab in der letzten Zeit vermehrt RAM Probleme entdeckt
(Memtest v1.86+ als CD-ISO) die teilweilse erst nach 48 Stunden mit
100% CPU Last auftraten wobei ich teilweise sogar "innere" Lüfter für
den Test abgeschaltet hatte um die RAM´s richtig "zu kochen".

Zum Glück werden seit SDRAM Zeiten bei uns nur noch Kingston RAM
benutzt sodas ich wenigstens Gutschriften "zum Tagespreis" bekam.

Also wenn mal wieder eine Kunde ankommt mit auf "seinem" alten PC
(> 3 Jahre) würde was nicht funktionieren aber auf allen anderen geht
es dann kann man den Kunden nur sagen er soll sich für 199,- Euro
einen neuen PC kaufen da der alte doch eh (hoffentlich) abgeschrieben
ist un das "suchen" nach solchen Hardware Fehler den Preis leicht über-
steigen kann (Arbeitszeit + Ersatz-Hardware)

gruss by OHR
Jimmy
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Tom:
Das kann m.E. einige Ursachen haben, zum Beispiel Fehler in dieser (eigenen?) Methode "GetValue“. - oder Zeichensatztransformationsfehler. Enthält das fragliche Feld im Fehlerfall Umlaute oder ähnliches? "
Dies glaub ich nicht. Dann müsste der Fehler unter Zugrundelegung der gleichen Datenbasis unabhängig des Arbeitsplatzes und des Netzwerkes reproduzierbar sein. Zum anderen enthält das entsprechende Feld nur Ziffern.

Hubert:
Technisch gesehen hasst Du Recht. Gleichwohl dessen habe ich festgestellt, dass meine Anwendung sich unter CIRTIX in einigen Punkten anderes verhält als in einer „normalen Windows-Session“. So z.B. verlor die Anwendung bei bestimmten Situationen den Fokus und wechselt zu Outlook. Nur durch den Einsatz von Windows-API Funktionen konnte das Problem behoben werden.

Die Ursache mag auch im VPN-Netzwerk selbst liegen. Die Außenstelle ist durch eine 2Mbit DSL-Leitung mit dem Server verbunden. Die Datenpakete nehmen schon mal einen Umweg von Hamburg nach Bremen über New York und wieder zurück.

Jim:
Die IT-Abteilung des Kunden wird mir den Vogel zeigen, wenn ich mit diesem Vorschlag käme. Es würde 2 Rechner betreffen. Und wenn deren Test ergeben würde, dass die RAM´s ok sind und sie dennoch die Rechner austauschen würden und anschließend das Problem wieder auftaucht, braucht es nicht viel Fantasie, um zu wissen wer den Schwarzen Peter hätte. ;-)


Beste Grüße
Olaf
hschmidt
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 164
Registriert: Mo, 09. Jan 2006 17:06
Wohnort: Paderborn
Hat sich bedankt: 2 Mal
Kontaktdaten:

Beitrag von hschmidt »

Hallo Olaf,
Schonmal die Werte innerhalb dieser Abfrage protokolliert oder in einem Debug-Fenster ausgegeben?
ich kann diese Anregung von Tom nur unterstützen. Ich würde die Werte und vielleicht einige Zusatzinfos (Alias, Indexkey, Scope, Trace, Benutzername...) in eine Protokolldatei schreiben.
Diese Informationen kannst Du dann anschließend in Ruhe auswerten.

Hans
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hallo Hans,
guter Vorschlag, nur leider aus folgenden Gründen nicht praktikabel:

- Der Fehler tritt nur beim Kunden auf
- Der Fehler ist nicht reproduzierbar

Sicherlich könnten beim Auftreten dieses Fehlers zur Fehleranalyse zusätzliche Informationen des aktuellen Programmzustandes in einer ASCII-Datei gespeichert werden. Diesen Gedanken werde ich mal umsetzten.
Benutzeravatar
Rolf Ramacher
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1930
Registriert: Do, 09. Nov 2006 10:33
Wohnort: Bergheim
Danksagung erhalten: 3 Mal
Kontaktdaten:

Beitrag von Rolf Ramacher »

Hi Olaf,

nochmal das Phänomen tritt nur bei diesem einem Kunden auf ?
Arbeitet nur ein Rechner mit deinem Programm oder mehrere Rechner?

An diesem Rechner muß doch irgendetwas anders sein als bei den anderen. (Netzwerkkarte,Kabel,Einstellungen,Treiber ect)
Gruß Rolf

Mitglied der Gruppe XUG-Cologne
www.xug-cologne.de
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hi Rolf,
das Problem trat bis dato nur beim Kunden auf. Die Anwendung läuft im Netzwerk unter CITRIX.

Gegen evtl. fehlerhafte Netzwerkeinstellungen oder defekte Komponenten spricht der Umstand, dass alle anderen Anwendungen auf den Kundenrechnern auch unter CITRIX fehlerlos laufen. Allerdings sind die anderen ERP-Anwendungen reine Client-Server Programme bei denen die Daten mittels eines SQL-Servers verwaltet werden.

Gruß, Olaf
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Lewi hat geschrieben: Es würde 2 Rechner betreffen.
auch so. ich bin von "einem von XXX" ausgegangen der spinnt
Lewi hat geschrieben: Die Ursache mag auch im VPN-Netzwerk selbst liegen. Die Außenstelle
ist durch eine 2Mbit DSL-Leitung mit dem Server verbunden. Die
Datenpakete nehmen schon mal einen Umweg von Hamburg nach
Bremen über New York und wieder zurück.

Ferner werden alle Speicherungsvorgänge mit einem Commit() und
Skip(0) abgeschlossen.
ok nun wird es klarer und ich tippe auf Opportunistic locking und würde
FOXDBE_LIFETIME auf 0 setzten.
Lewi hat geschrieben: ... eines SQL-Servers
ist das der selbe Server ? Wenn ja dann sieh dir mal die Op´s Lock
Einstellungen an die ein M$ (?) SQL-Servers "benötigt" die aber
Xbase++ gar nicht mag ...

workaround : 2 Server, einen NUR für Xbase++ optimiert und der
andere für den M$ Sc.....

gruss by OHR
Jimmy
Benutzeravatar
Lewi
1000 working lines a day
1000 working lines a day
Beiträge: 830
Registriert: Di, 07. Feb 2006 14:10
Wohnort: Hamburg
Danksagung erhalten: 2 Mal

Beitrag von Lewi »

Hi Jimmy,
der SQL-Server läuft auf einer separaten Maschine.

Der Kunde hat 2 Citrix-Server, wobei je nach Last der 2. Server hinzugeschaltet wird.

Ich habe bisher für die Dbe (FOXCDX) keine besonderen Einstellungen vorgenommen und nutze die Standardeinstellungen.

Welche Einstellungen unter 1.82 würdest Du empfehlen?


Beste Grüße
Olaf
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Beitrag von AUGE_OHR »

hi,
Lewi hat geschrieben: der SQL-Server läuft auf einer separaten Maschine.
gut so !
Lewi hat geschrieben: Ich habe bisher für die Dbe (FOXCDX) keine besonderen Einstellungen vorgenommen und nutze die Standardeinstellungen.

Welche Einstellungen unter 1.82 würdest Du empfehlen?
kann nur Erfahrungen mit der v1.9x mitteilen und auf die "Hilfe" verweisen
Hinweis: Wird die FOXDBE-DatabaseEngine in Anwendungen mit
mehreren Threads eingesetzt, sollte FOXDBE_LIFETIME unter Umständen
auf den Wert 0 gesetzt werden. Dies ist der Fall, wenn mehrere Threads
auf der selben DBF-Tabelle operieren und das Zeitfenster für Updates auf
der Datenbasis kleiner ist, als die Verweildauer der Datensätze im Cache.
Unter diesen Umständen ist die Korrektheit bzw. Aktualität der auf der
Client-Maschine vorgehaltenen Daten nicht gewährleistet. Dies betrifft in
erster Linie Lösungen, die mit dem Web Application Adaptor (WAA)
entwickelt wurden oder auch Applikationsserver-basierte Anwendungen,
in denen die Frequenz des Datenzugriffs von der Auslastung des
Serversystems abhängig ist.
zusammen mit SKIP 0 / Commit sollte damit der "locale" Cache geleert
werden aber nun kommt ja noch das (W)Lan.

Hier hab ich nun auf den Server (W2K3) die Op´s lock Einstellungen für
die Netzwerke dem "langsamsten" angepasst und auch in der DBESYS
die Werte LOCKRETRY um Faktor 1000 erhöht und LOCKDELAY auf den
"kleinst" möglichen Wert gesetzt (ausprobieren).

Code: Alles auswählen

LOCAL nLevel := VAL(GETENV("myPCspeed"))

CASE nLevel > 10
   // schnelle PC, Zeit erhöhen damit die andern Zeit bekommen
   DbeInfo(COMPONENT_ORDER,CDXDBE_LOCKDELAY,30)

CASE nLevel < 10
   DbeInfo(COMPONENT_DATA,FOXDBE_LOCKRETRY,100000000)

   DbeInfo(COMPONENT_ORDER,CDXDBE_LOCKRETRY,100000000)
   // langsame PC, Zeit minimum (<4 geht nicht ?)
   DbeInfo(COMPONENT_ORDER,CDXDBE_LOCKDELAY,4)
Damit laufen die "langsamen" P3 Rechner zusammen mit den "schnellen"
P4 Rechnern und zu 99% auch WLan ...

gruss by OHR
Jimmy
Antworten