FoxPro

FoxPro Developer's Conference '94

Session 131

Grundlagen der netzwerkfähigen Programmierung

Jürgen Wondzinski
ProLib GmbH


Einführung

Schon seit ca. 1988 an wurde in der Fachliteratur mit schöner Regelmäßigkeit jedes Jahr als das "Jahr des Netzwerks" bezeichnet. Durch ständig sinkende Hardwarepreise wurden Netzwerke nun auch in den kleinen Büros interessant, so daß nun viele zuerst als Einzelplatzanwendung geschriebene Programme auf den Multiuser-Betrieb umgestellt werden müssen. Diese Änderungen betreffen zum Einen Anpassungen an neue Funktionen, die nur ein Netzwerk bietet (Drucker-Spooling, Transaction Tracking, Email), zum Andern die durch Multiuser-Betrieb entstehenden Problematiken wie Datei- und Satzsperren usw. Aber gehen wir erst mal Schritt für Schritt vor:


Unterschied SingleUser zu MultiUser:

In der normalen Einzelplatzumgebung läßt sich's einfach programmieren: Man ist Herr der Dinge, während man einen Datensatz ändert, kann nichts anderes mit ihm passieren. Ganz anders ist die Situation im Netzwerk: Da mit Ihnen noch andere Stationen gleichzeitig mit den Daten arbeiten, ist es normalerweise die Ausnahme, daß Sie z.B. ohne weitere Vorkehrungen einfach einen PACK durchführen können.

Grundsätzlich gilt außerdem, daß nur die Daten gemeinsam zur Verfügung stehen. Alle Variablen, Arrays und SQL-Cursordateien sind nur auf dieser einen Station sichtbar. Es ist nicht möglich, daß eine andere Station Ihre Cursordatei überschreibt. Wichtig ist ebenfalls, daß jede Station einen eigenen Satzzeiger (Recordpointer) hat, ebenso wie jede Station die Indexsortierung unabhängig voneinander einstellen kann.

Dadurch, daß die Daten zentral an einem Ort (dem Server) gehalten werden und alle Anwender gleichzeitig Zugriff zu den Daten haben und z.B. neue Datensätze anlegen oder sie verändern, müssen Sie spezielle Vorsichtsmaßnahmen walten lassen, damit dies alles ohne Probleme abläuft.

Gottseidank sind die prinzipiellen Änderungen bei FoxPro nicht allzu kompliziert, denn:

Die grundsätzliche Änderung besteht eigentlich nur im Einfügen zweier Befehle in ihrem Startprogramm, noch bevor irgendeine Datei geöffnet wird.

Damit kommen Sie schon ganz gut über die Runden! Ab sofort wird jede Datei im SHARED Modus geöffnet, und FoxPro kümmert sich um die erforderlichen Sperren.

Klingt zu gut um wahr zu sein, nicht wahr? Nun ja, wenn's soo einfach wäre, müsste ich mir hier nicht die Finger platt tippen.... Also, schaun mer mal.


Datei- und Satzsperren

In FoxPro gibt es verschiedene Abstufungen in der Steuerung des Datenzugriffs:

SHARED:

RECORD LOCK:

FILE LOCK:

EXCLUSIVE:

Diese Tabelle zeigt, welche Sperren FoxPro automatisch bei bestimmten Befehlen setzt:

 

Befehl Sperrt:
APPEND FILE
APPEND FROM FILE
DELETE [ALL | REST | NEXT x] FILE
REPLACE [ALL | REST | NEXT x] FILE
UPDATE FILE
APPEND BLANK HEADER
INSERT INTO HEADER
APPEND MEMO RECORD
DELETE [NEXT 1] RECORD
GATHER RECORD
MODI MEMO RECORD
READ RECORD
RECALL [NEXT 1] RECORD
REPLACE [NEXT 1] RECORD und alle angegebenen Dateien in der FIELD Anweisung
BROWSE
EDIT
RECORD und alle relationierten Sätze
DELETE RECORD x RECORD x
REPLACE RECORD x RECORD x

Bei "Header"-Sperren wird von FoxPro nur der Dateikopf für den Zeitraum des Anfügens einzelner Datensätze gesperrt (Im Header ist z.B. die Anzahl Sätze und das letzte Zugriffsdatum gespeichert). Dies ist Multiuser-freundlicher als eine komplette Dateisperre.

Wenn eine Datei auf einer Station im Exclusive Modus geöffnet ist, und Sie von einer anderen Station versuchen, ebenfalls diese Datei zu öffnen, belohnt sie FoxPro mit der Fehlermeldung #3 "Datei wird bereits benutzt". Falls Sie ein DOS Netzwerk einsetzen (alles, was SHARE benötigt) können Sie auch die Fehlermeldung #1705 "Zugriff auf Datei verweigert" erhalten. Sie sollten also Ihre Datei-Öffnungs Routinen dementsprechend erweitern. Ebenso müssen Sie in Betracht ziehen, daß Sie eine Datei nicht exclusiv öffnen können, weil eben noch ein anderer Anwender die Datei offen hat.

Prinzipiell müssen Sie durch eine geeignete LOOP Konstruktion solange probieren, bis Sie den Zugriff bekommen (oder der Anwender abbricht).

Ob Sie die Fehlerbehandlung direkt an Ort und Stelle, wie bei obigen Beispiel, durchführen, oder die Kontrolle einer zentralisierten Fehlerroutine übergeben, bleibt Ihren Vorlieben überlassen. Auf der beiliegenden Diskette finden Sie einen mustergültigen Errorhandler von Pat Adams, jeweils als DOS und als Windows Version, der Ihnen zumindest als Fundquelle jeglicher Fehlerbehandlung dienen kann.

Haben Sie nun die Datei erfolgreich öffnen können, ist der weitere Ablauf zuerst einmal identisch zum normalen SingleUser Betrieb: BROWSE, SEEK, usw. funktionieren wie gehabt. Der große Unterschied kommt nun erst beim Verändern der Daten. Egal was sie mit einem Datensatz auch anstellen: Sie müssen den anderen Anwendern im Netz mitteilen, daß dieser Datensatz nun von Ihnen bearbeitet wird. Dies erfolgt normalerweise durch Setzen der Satzsperre mittels RLOCK().Sobald Sie einen Datensatz erfolgreich gesperrt haben, können andere Anwender nur noch lesend auf ihn zugreifen. Nach Beendigung Ihrer Arbeiten wird der Satz mittels UNLOCK wieder freigegeben und ihre Änderungen den anderen Anwendern zur Verfügung gestellt.

Problematisch:

Ohne Satzsperren:    
User A Zeit ê User B
Satz lesen   Satz lesen
    Editieren
Editieren    
    Speichern
Speichern    

Bei diesem Beispiel lesen beide Anwender den selben Datensatz, und beschließen beide, eine Änderung zu machen. User B kann schneller tippen, ist daher früher fertig und speichert ab. User A überschreibt nun mit seinem Speichern alle Änderungen von User B. Sicherlich nicht Sinn eines Netzwerks...

Und so sollte es richtig ablaufen:

Mit Satzsperren:    
User A Zeit ê User B
Satz lesen   Satz lesen
    Satz gesperrt !
Satz sperren ?   Editieren
Satz sperren ?    
Satz sperren ?   Speichern
Satz gesperrt   Entsperren
Satz lesen    
Editieren    
Speichern    
Entsperren    

Durch die Satzsperre muß User A solange warten, bis User B mit seinen Änderungen fertig ist. Erst nach Freigabe kann User A den Datensatz (mit den Änderungen!) nochmals neu einlesen, selbst sperren und bearbeiten.

Ein nicht unwesentlicher Teil von FoxPro's Geschwindigkeit beruht auf den ausgefeilten Datenpufferungs-Methoden. Beim Öffnen liest FoxPro nämlich einen Teil der Daten schon vorweg in seinen Speicher. Alle weiteren Zugriffe auf diese Datensätze erfolgen dann auf diesen Zwischenspeicher. Bei einem Einzelplatzrechner haben Sie damit auch keinerlei Probleme. Im Netzwerkbetrieb kann allerdings folgendes auftreten:

User A und User B stehen (wieder einmal) auf dem selben Datensatz. User A sperrt den Datensatz. Beide kopieren sich den Datensatz in ein Array (z.B. mit dem SCATTER Befehl). User A editiert, speichert seine Änderungen ab und entlässt den Datensatz aus seiner Sperre. User B macht ein erneutes SCATTER, um die Änderungen von User A zu erhalten, aber.... er bekommt die selben Inhalte wie bei dem Scatter vorher! Soviel Sie auch SCATTERn, sie sehen die geänderten Daten nicht. Ursache ist eben jener Puffer: Alle Lese und Schreibaktionen werden auf den Puffer ausgeführt und nicht gegen die "echten" Daten im Netzwerk. Um diesen Effekt auszubremsen müssen Sie FoxPro dazu bringen, den Puffer neu einzulesen:

Die beste Methode ist zweifellos die dritte Option: Grundregel aller Netzwerkanwendungen: Willst du saubere Daten haben, dann mußt du diese sperren. Unser obiges Beispiel können wir also zum ordnungsgemäßen Laufen bringen, indem wir vor dem zweiten SCATTER ein einfaches RLOCK anbringen.

Nun ist es aber in manchen Anwendungen unerwünscht, den Datensatz nur aus Gründen des Puffer-Auffrischens zu sperren. Dann hilft am besten Methode zwei: Ein seltsam anmutendes GOTO RECNO() erledigt dies elegant. FoxPro tritt sozusagen auf der Stelle, aber der Puffer hat den neuesten Wert.

Die SET REFRESH Option ist, da sie zu einem ständigen Neueinlesen alle <x> Sekunden führt, ein Netzwerk-Performance Killer. Stellen Sie sich 20 oder 50 Stationen vor, die allesamt z.B. jede 5 sec. ihren Puffer erneuern, sprich: die nächsten 10 oder 20 Datensätze frisch einlesen. Daher sollte die SET REFRESH Einstellung nur dann ungleich 0 gesetzt, wenn sie wirklich benötigt wird. (Mehr dazu noch beim Thema BROWSE)

In so ziemlich allen Anwendungen werden temporäre Dateien angelegt und wieder gelöscht. In Einzelplatzanwendungen werden dieDateinamen dafür meist fest vorgegeben (wobei "TEMP" sicherlich der mit Abstand meist verwendete Name sein dürfte J ). Davon müssen Sie sich in Netzwerkumgebungen leider trennen. Über die Funktionen SYS(3) und SYS(2015) können sie sich jederzeit einen eindeutigen Dateinamen zusammenstellen. Die Wahrscheinlichkeit, daß diese Funktionen einen doppelten Dateinamen zurückgeben ist sehr gering. Persönlich habe ich es auf einem sehr schnellen Rechner schon geschafft, bei zwei direkt hintereinander liegenden SYS(3) Aufrufen dieselbe Zeichenkette zurückzubekommen. Dies kommt vermutlich in der Praxis kaum vor, aber hier hilft das einfache Einfügen von einem weiteren Programmschritt zwischen den beiden SYS(3) Aufrufen.

Viel wahrscheinlicher (und trotzdem äussert selten) ist das gleichzeitige Vergeben desselben Dateinamens von unterschiedlichen Netzwerkstationen. Dies ist mir allerdings schon des öfteren gelungen: Bei Schulungen ist dies ein beliebter Vorführeffekt. (Alle Schüler starten gleichzeitig eine Testfunktion). Der von SYS(3) zurückgegebene Wert beruht auf Systedatum und Uhrzeit, und nachdem die Systemuhren der Rechner beim Einloggen in Novell automatisch synchronisiert werden, ist dies also leicht möglich.

Die neuere Funktion SYS(2015) nimmt daher noch Informationen aus dem RechnerBIOS heran, um die Nummern eindeutiger zu machen. Mit dieser Funktion ist mir der obige Effekt noch nie gelungen. Allerdings ist der zurückgegebene String zehnstellig, sodaß sie für einen Dateinamen nur die letzten acht Stellen verwenden sollten.

Des weiteren sollten Sie alle temporären Dateien im EXLUSIV Modus öffnen. Auf diese Weise erhöhen Sie die Geschwindigkeit und die Sicherheit, daß nicht aus Versehen eine temporäre Datei von einer anderen Station mitverwendet wird. Cursordateien sind übrigens prinzipiell exclusiv, da sie ja nur im Speicher Ihrer Arbeitsstation existieren.

 

 

Außerdem ist es eine gute Methode, das Temporärverzeichnis auf die lokale Platte zu legen (siehe TMPFILES Eintrag in der CONFIG.FPW), und alle temporären Dateien dort anzulegen. Falls die TMPFILES Einstellung nicht existiert, verwendet FoxPro/WIN das TEMP-Verzeichnis von Windows; FoxPro/DOS das aktuelle Arbeitsverzeichnis.

Den Pfad dieses Verzeichnisses erhalten Sie mit der SYS(2023) Funktion. Dummerweise hat diese Funktion zwei gravierende Mängel: Zum Einen überprüft sie nicht das Vorhandensein dieses Verzeichnisses (Problem entsteht z.B. durch Schreibfehler in der CONFIG.FPW, oder Directory gelöscht/umbenannt); zum Zweiten liefert sie unterschiedliche Ergebnisse unter FoxPro/DOS und /WIN:

Hier nun eine Ersatzfunktion, die Ihnen das tatsächlich von FoxPro verwendete Verzeichnis zurückliefert:

Die Funktion beruht auf der Tatsache, daß Cursordateien immer im Temporärdirectory verankert werden. Als kleine Annehmlichkeit am Rand ist diese Pfadangabe auch immer mit einem Backslash abgeschlossen.

Hier müssen wir unterscheiden zwischen den Rechten für das Applikationsverzeichnis und den Rechten im Datenverzeichnis. In Netzwerken ist es allgemein üblich Programme und Daten in getrennten Verzeichnissen zu halten. Dies zum Einen aus Gründen der einfacheren Datensicherung, zum Anderen aus Gründen des Zugriffsschutzes.

Unter der Voraussetzung, daß die FoxUser.dbf und die temporären Daten in einem lokalen Verzeichnis gehalten werden, benötigt das Applikationsverzeichnis nur SCAN und READ Zugriff. Für das Datenverzeichnis müssen normalerweise alle Rechte vergeben sein (READ/WRITE/SCAN/ERASE).

Beim Abprüfen auf existierende Verzeichnisse ist diese Methode weit verbreitet:

Unter Novell ist diese Methode leider nicht brauchbar, sie meldet immer .T.. Auch sagt das Vorhandensein eines Verzeichnisses noch lange nichts darüber aus, ob sie tatsächlich auch das Verzeichnis beschreiben dürfen. (Möglicherweise haben sie ja nur Leserecht). Aus diesen Anforderungen entstand daher die folgende Routine:

Unter Einzelplatzanwendungen war es eine beliebte Methode, globale Einstellungen in einer MEM Datei abzuspeichern. Im Netzwerk haben diese Dateien leider einen Nachteil: Sie werden exklusiv geöffnet, während sie gelesen oder geschrieben werden. Wenn z.B. zwei Stationen genau zur selben Zeit gestartet werden, kann es vorkommen, daß beide versuchen, dieselbe MEM-Datei zu lesen. Dabei bleibt einer auf der Strecke...

Speichern Sie daher alle Ihre Variablen anstelle von der MEM Datei in ein MEMO Feld ab. Dies ist eine relativ unbekannte Fähigkeit von FoxPro :

Der Effekt ist derselbe wie bei der MEM Datei, dafür haben Sie aber einen sauber geregelten Multiuser-Zugriff.

Generell ist es für solche Grundeinstellungen aber besser, eine zentrale SYSTEM.DBF zu erstellen, die alle Grundwerte enthält (z.B. MwSt, Firmenaddresse, Lizenznummer, usw.) Legen Sie diese Daten als echte Datenbankfelder ab und lassen sie die Datei ständig offen (bei 225 Arbeitsbereichen auch keine Belastung). Dadurch haben Sie diese Werte ständig über Alias-Referenz in allen Programm-Modulen zur Verfügung und müssen nicht teuren Variablennplatz belegen.

Das BROWSE ist eines der mächtigsten Teilmodule innerhalb FoxPro's. Auch im Netzwerk zeigt es überragende Fähigkeiten: Alle erforderlichen Sperren und Aktionen werden vollkommen selbsttätig ausgeführt. Durch das sog. "Dirty Read" Verfahren können Sie durch die Tabellen blättern, ohne sich um Satz- oder Dateisperren zu kümmern. Sobald Sie in einem BROWSE-Feld das Editieren anfangen, wird versucht, diesen Satz zu sperren. Solange dies nicht klappt, erscheint der Warnhinweis "Versuche zu sperren - ESC zum Abbruch" Sobald der Datensatz wieder frei wird, wird ein automatischer Refresh durchgeführt. Falls in dem Browse auch relationierte Felder mit angezeigt werden, so wird der betreffende Satz in der Tochterdatei ebenfalls gesperrt; bei SET SKIP TO (1:n Relation) auch alle zum Hauptsatz gehörenden Tochterdatensätze. Also ein Musterbeispiel an netzwerkfreundlicher Programmierung und ein optimales Werkzeug, um die verschiedenen Sperrfolgen selbst auszutesten...

Trotzdem tritt auch hier im Browse das Problem der Puffer auf: Alle angezeigten Datensätze innerhalb des Fensters werden ja einmal eingelesen und sind dann statisch. Wenn Sie also den Recordpointer nicht verschieben, werden auch die Datensätze nicht neu eingelesen, und sie sehen Änderungen, die im Netz gemacht werden, nicht. Hier allerdings kommt nun der SET REFRESH Befehl ins Spiel: Sein erster Parameter bestimmt, wie oft die angezeigten Daten im BROWSE neu eingelesen werden.

Nun werden alle fünf Sekunden die 10 bis 15 Datensätze im Browsefenster neu eingelesen. Ein Kunde von mir, er ist Besitzer eines Lebensmittelmarktes, sitzt nun am liebsten im Büro vor seinem Browse-Fenster, und sieht zu, wie die Warengruppenumsätze kontinuierlich ansteigen, während draussen die Kassen fleissig das Umsatzfeld im Artikelstammsatz erhöhen....

Leider funktioiert dieses automatische Ändern nicht mit Popups a la:

Dieses Popup wird nur beim ersten Mal erstellt, es wird nicht durch den SET REFRESH Vorgang erneuert. Falls sich die hiermit angezeigten Daten sehr häufig ändern, müssen Sie entweder das Popup jedesmal frisch einlesen, oder auf die Verwendung von Browse umsteigen.


Direktes oder indirektes Editieren

Soll man nun direkt die Datenbankfelder im READ bearbeiten oder besser doch den Datensatz auf Speichervariablen umkopieren und dann bearbeiten? Die Frage ist so alt wie dBase und kann sehr leicht in einen Glaubenskrieg ausarten. Beide Methoden haben ihre Vor- und Nachteile, und je nach Anwendungsfall kann das Ergebnis anders ausfallen.

Wie immer bei religiösen Angelegenheiten, bringt ein Blick in die Vergangenheit etwas Licht ins Dunkel:

Als dBase II anno 1981 auf den Markt kam, war die Dateistruktur mehr als wacklig. Die Daten konnten sehr leicht beschädigt werden, und vor allem konnte dBase damals nur zwei Arbeitsbereiche verarbeiten. Damals wurde aus dieser Zwangslage heraus eine spezielle Programmiermethode entwickelt: Datei öffnen, Datensatz in Variablen kopieren, Datei schließen. Nur keine Risiken eingehen! Nach dem Editieren wurde die Datei wieder geöffnet, der Datensatz geschrieben, und sofort wieder geschlossen. Mit Erscheinen von dBaseIII+ wurde das Produkt wesentlich stabiler, doch trotz MultiUser-Fähigkeiten mußte man selbst für die Recordlocks sorgen. Die zehn Arbeitsbereiche sorgten zwar dafür, daß man nicht mehr so oft die Dateien schliessen mußte, aber ansonsten gab es noch keinen Grund, von den erprobten Methoden abzuweichen.

Mit Erscheinen von FoxBase/LAN, das wesentlich stabiler und schneller als dBaseIII+ war, hielten erste automatische RecordLocks Einzug. Da aber die Implemetierung nicht vollständig war, blieben die meisten Programnmierer beim Variablen-Editieren. Aber seit dem Erscheinen von FoxPro 1.0 hat sich das Blatt gewandelt. Erstmals war es nur noch in Sonderfällen notwendig, explizite Sperren zu setzen, erstmals erledigte die Engine das meiste. Aus diesen Gründen heraus begannen viele Programmierer den Umstig zur direkten Editierung:

Gegen das direkte Editieren werden gerne zwei Gründe angeführt:

Zu Punkt eins ist zu sagen, daß meine Beobachtungen darauf hindeuten, daß Änderungen in der Regel gewollt sind, und nur in Ausnahmefällen abgebrochen wird. Auch ist die Netzwerk und PC-Hardware in der heutigen Zeit so zuverlässig geworden, daß Rechnerabstürze eher selten geworden sind. (Nun gut, bei uns als Entwicklern ist das anders... J ) Falls also beim direkten Editieren ein Vorgang abgebrochen werden muß, so genügt das Sicherstellen des Datensatzes in einem Array vor Beginn des Editierens. Nur bei einem Abbruch muß dann dieses Array zurückgesichert werden. Der generelle Ablauf sieht also etwa so aus:

Beim indirekten Editieren sind so ziemlich die selben Schritte notwendig:

Daraus folgt, daß vom grundlegenden Schema her das direkte Editieren den Sieg davontragen kann. Ähnlich sieht es aus, wenn man die Programmierung betrachtet.

Dafür ist beim direkten Editieren der zentrale Dreh- und Angelpunkt ein sauber funktionierendes Fehlermanagement. Hier sei nochmals auf die ProError und ProErrorW Datei hingewiesen. In Verbindung mit diesem ausgefeilten Errorhandler können 99% aller Multiuserprobleme getrost vergessen.

Der andere Punkt (Datensatz ist dauerhaft gesperrt) spielt bei FoxPro eine eher untergeordnete Rolle, denn selbst wenn der Satz durch das READ gesperrt ist, kann er ja immer noch gelesen werden! Und auch beim Variablen-Editieren ist eine Grundvoraussetzung das saubere Sperren während die Variablen editiert werden.

Die Alternative zu diesem pessimistischen Locking ist das optimistische Locking, nach dem Motto: Ich brauch den Datensatz im Normalfall nicht sperren".

In einem zusätzlichen Feld in der Datei wird bei jedem Update ein Zähler oder ähnliches hochgezählt. Ab und an trifft man auch Versionen, die Datum, Uhrzeit und User hier abspeichern). Beim Einlesen des Datensatzes merkt man sich diesen Wert, beim Abspeichern der geänderten Daten muß nun zuerst überprüft werden, ob der Stand im Zählerfeld noch identisch ist. Wenn ja, ist alles gut gegangen, mein Optimismus wurde belohnt, und ich kann die Daten abspeichern. Wenn nein, dann ist der Anwender arm dran, denn nun wird der inzwischen geänderte Datensatz neu eingelesen und unser Anwender darf seine Änderungen nochmals neu erfassen. Durch etwas Mehraufwand kann man nun noch erreichen, daß man Feld für Feld abprüft welches sich überhaupt geändert hat, und nur diese Felder nachbearbeiten läßt.

Unter gewissen Sonderfällen wird eine Spezialform des optimistischen Sperrens durchgeführt: Wenn in einem System zwei verschiedene Datenbereiche einer Datei von zwei verschiedenen Abteilungen gepflegt werden, kann es Sinn machen, auf Variablen zu editieren und den Datensatz nicht dauerhaft zu sperren. Dadurch, daß jeder Prozess nur einen Teil der Felder bearbeitet, und keine Übserschneidungen vorkommen, können beide Update-Prozesse parallel laufen.

Alles in Allem ein wesentlicher Mehraufwand, dessen Nutzen meist in keinem Verhältnis zum Aufwand steht. Desweiteren können bei Verwendung solcher Sperrmechanismen keine Fremdprogramme mehr mit den selben Daten arbeiten, da sie von diesen Regeln keine Ahnung haben.


Hardware Grundlagen

Egal, welches Netzwerk Ihr Kunde einsetzt: um Ihre Programme sauber auszutesten, müssen Sie sich selbst auch entsprechend ausrüsten. Nur so können Sie sich hundertprozentig von der Betriebssicherheit Ihrer Programme überzeugen, und dabei gleich auch noch Netzwerkwissen sammeln.

Im einfachsten Fall tut´s ein normaler Multitasking Zusatz wie z.B. DESQview (Quarterdeck) oder unser allseits beliebtes WINDOWS. Dazu muß auch zwingend SHARE geladen sein, damit DOS den Mehrfach-Dateizugriff auch verwalten kann. Beim SHARE Aufruf unbedingt die Zusatzparameter mit angeben: z.B.

ansonsten erhalten Sie über kurz oder lang die kryptische Fehlermeldung "Systemresourcen erschöpft".

Besser ist's schon mit Windows For Workgroups (im folgenden kurz als WinWG bezeichnet): Hier kommt zum Einen ein virtueller Share Treiber (VSHARE.386) zum Einsatz (d.h. unter WinWG muß kein SHARE mehr in der Autoexec geladen werden!). Zum Andern kann man zusammen mit seinem Laptop oder einer anderen Station schon ein kleines Netzwerk aufbauen.

Noch besser ist natürlich die Anschaffung einer 5User Version von Novell, zusammen mit WinWG. Damit haben Sie dann so ziemlich alle Möglichkeiten, die Ihnen im normalen Business vorkommen werden, abgedeckt. Zum Einen können Sie die Novelltypischen Sachen wie Druckspooling, Transaction Tracking usw. verwenden und austesten, zum anderen haben Sie via WinWG auch die "normalen" DOS basierenden Netzwerke im Zugriff. Dem Thema Novellkonfiguration habe ich nachfolgend noch ein Extrakapitel gewidmet.

Später läßt sich diese Konstellation dann noch um einen WinNT Server, erweitern, so daß Sie dann auch noch den MS SQLServer in ihr Netz einbinden können und auf Client/Server Basis programmieren können. Sie sehen, in den nächsten Monaten werden Sie keinerlei Probleme haben, ihr Geld sofort wieder zu investieren....

So, ihr Netzwerk ist aufgebaut. Jetzt geht's ans Einrichten. Wenn möglich sollte ihre Installation so aussehen:

Lokale Platte:

Netzwerk:

In einem großen Netzwerk kann das lokale Installieren von Windows und sonstigen Programmen zu einem Support-Alptraum ausarten, darum wird man dort auf eine Netzwerk-Installation umsteigen. Dies bedeutet, daß alle Programme zentral im Netzwerk liegen, und lokal nur noch die benutzerspezifischen Abweichungen gespeichert werden (INI-Dateien usw.). Dies geht zwar auf Kosten der Performance (alle Programmdateien müssen über das Netzwerk geladen werden) dafür muß z.B. bei einem Update nicht durch das gesamte Haus geturnt werden.

Bitte beachten Sie, daß trotz der Verwendung von nur einer Programmkopie auf dem Server weiterhin Lizenzen für alle angeschlossenen Arbeitsplätze vorhanden sein müssen.

Doch nun zurück zu FoxPro:

Die relativ große Supportbibliotek (FOXPRO.ESL) sollte wenn möglich, auf der lokalen Platte abgelegt werden. Dadurch erfolgt der Start Ihrer Applikation wesentlich schneller. Des weiteren sollten auch alle temporären Dateien lokal gehalten werden. (TMPFILES Eintrag in der CONFIG.FP)

Wenn in einem Netzwerk unterschiedliche Rechnerkonfigurationen existieren, so muß dafür gesorgt werden, daß für jeden Arbeitsplatz eine eigene CONFIG.FP zuständig ist. Über die DOS Variable FOXPROCFG (oder FOXPROWCFG bei FP/WIN) kann zentral der Zugriff auf diese Datei geregelt werden, z.B. indem ein Directory User- bzw. Stationsbezogen gemappt wird. So ist z.B. in meinen Netzwerken das Laufwerk H: immer das Heimatverzeichnis des angemeldeten Users. Darin existiert wiederum ein FoxPro Unterverzeichnis mit seiner CONFIG.FPW, seiner FOXUSER.* usw.

Im Normalfall wird man jedem Anwender seine eigene FOXUSER Datei gönnen, alternativ kann man aber auch allen Anwendern gemeinsam eine zentrale FOXUSER zur Verfügung stellen. Diese muß aber dann auf READ-ONLY gesetzt werden. Falls dies nicht geschieht, greift das erste im Netz gestartete FoxPro im Exklusivmodus auf diese Datei zu, während die nachfolgenden daher keinen Zugriff mehr erhalten.

Sie können die Geschwindigkeit im Netz noch weiter optimieren, indem Sie generell die Verwendung von Resourcedateien unterbinden (SET RESOURCE OFF). FoxPro kann sich dann allerdings keine Fensterpositionen, Rechner- und Kalendereinträge mehr merken, und in FP/DOS gehen ihnen dazu noch die Farb- und Druckereinstellungen verloren. Eine zweischneidige Sache also.


Netzwerk Tips

Prinzipiell können wir im FoxPro Bereich zwei Arten von Netzwerken unterscheiden:

Von der Verwendung dieser Netzwerke für echte Datenbankanwendungen wird abgeraten. Die Geschwindigkeit und Datensicherheit ist nicht akzeptabel, da auf der Station mit den Daten immer auch normal gearbeitet werden kann (NONdedizierter Server), besteht die Gefahr, daß diese Station durch Bedienerfehler abgeschossen wird. Daraus resultierend treten meist Platten- (lost Clusters) und Datenfehler ("Keine Tabelle", "Memodatei defekt") auf. Da solche Fehler im Zweifelsfall immer dem Programm bzw. Ihnen als Programmierer angelastet werden, sollten Sie von Anfang an den Kunden zumindest auf die Probleme solcher Konfigurationen hinweisen. Des weiteren haben meist Sie die Folgen auszubaden, sprich: die Daten zu restaurieren.

Setzen Sie alle EXE und Overlaydateien auf Read-Only, ansonsten könnten Sie durch unerklärliche Fehlermeldungen wie "Zugriff verweigert" beim Programmstart beglückt werden.

Da das meistverwendete Netzwerk immer noch das NOVELL Netzwerk ist, hierzu noch einige Tips:

Falls Windows eingesetzt wird, sollte die Workgroups Version installiert werden. Die Peer-to-Peer Eigenschaften ergänzen hervorragend die Novell-Eigenschaften.

Falls Sie noch immer mit den IPX-Treibern arbeiten: IPX ist tot, Novell empfiehlt seit Jahren nur noch die ODI Treiber. Doch inzwischen sind auch diese nicht mehr das Allerneueste: seit der 3.12 und 4.0 Version existiert das Konzept der VLM Module. Aus meiner Erfahrung heraus rate ich zur Zeit trotzdem noch zu den ODI Treibern, da damit alle Programme und Zusatzroutinen einwandfrei funktionieren. Die ODI Treiber haben gegenüber den IPX Treiber den Vorteil, daß sie modular aufgebaut sind. Dies hat u.a. den Vorteil, daß sie durch die geringeren Einzelgrößen leichter in den UMB-Bereich hochgeladen werden können. Bei Netzwerkkartentausch oder Umkonfiguration können die Änderungen durch einfaches Eintragen in der Datei NET.CFG durchgeführt werden, wohingegen der IPX.COM immer neu zusammenkompiliert werden mußte.

Die normale Workstation Konfiguration sieht demnach etwa so aus:

Config.sys

Autoexec.Bat

Sie sollten (wie immer) dafür Sorge tragen, daß nur die neuesten Treiber zum Einsatz kommen. Diese finden Sie am sichersten in CompuServe. Im Forum NOVFILES sind diese jederzeit zum Download bereit.

Falls sie eine ältere Installation auf Vordermann bringen, achten Sie darauf, daß der NETX früher eine COM Datei war, nun ist's eine EXE. Solange Sie aber die COM Datei nicht löschen, wird diese von DOS immer vor der EXE geladen! (Dies ist ein beliebter Trick, um sich stundenlanges Haareraufen zu bescheren...)

EMSNETX sollte immer dann zum Einsatz kommen, wenn Sie sowieso einen EMS Speichermanager verwenden, denn dann können Sie einiges an UMB-Bereich freihalten.

Alle Netzwerktreiber lassen sich übrigens ohne Probleme hochladen.

In dem Unterverzeichnis c:\netz aus obigem Beispiel muß sich noch die Datei NET.CFG befinden. Aus früheren Versionen ist Ihnen vielleicht noch die SHELL.CFG ein Begriff, diese sollten Sie aber sofort zu NET.CFG umbenennen. Diese Textdatei entspricht für Novell in etwa der Config.sys für DOS.

Standardmäßig können Sie nur 40 Dateien auf dem Netzwerk öffnen, erst durch die FILE HANDLES Anweisung wird dies erhöht. Die Summe der FILE HANDLES (Net.cfg) und der FILES (Config.sys) darf zusammen den Wert 254 nicht überschreiten!

Das Novell Dateisystem benötigt die DOS Verzeichniseinträge "." und ".." nicht, für die DOS Kompatibilität sollten Sie daher mit SHOW DOTS die Emulation durch Novell einschalten.

Da Novell standardmäßig die Umlaute in Datei- und Verzeichnisnamen nicht auf Großschrift wandelt, müssen Sie dies in europäischen Ländern gesondert einschalten mittels SPECIAL UPPERCASE.

Falls Sie an der Workstation keinen Drucker angeschlossen haben, können Sie den Wert bei LOCAL PRINTERS auf 0 setzen.

Die CACHE BUFFERS beschleunigen den Netzzugriff, kosten allerdings auch RAM.

Mit den LINK DRIVER Einträgen wird schließlich der eigentliche Netzwerkadapter konfiguriert; sie können bedenkenlos alle Konfigurationen aller verwendeten Netzwerkkarten hier aufführen, der Treiber sucht sich seinen zugehörigen Eintrag selbsttätig. (Wichtig ist die Einrückung der zugehörigen Werte!)

Im Novell Loginscript sollten Sie zum einen automatisch alle benötigten Standardverzeichnisse setzen, z.B. ein Heimatverzeichnis für jeden User getrennt und ein gemeinsames Datenaustausch-Verzeichnis. Zum anderen ist die MACHINE Anweisung hier zu setzen.

Falls Sie ThirdParty Tools verwenden, müssen Sie noch unbedingt diese Zeile in Novell's STARTUP.NCF eintragen:

Da Novell seit einiger Zeit die Paßwörter im Netzwerk verschlüsselt überträgt, der Algorithmus hierzu aber nicht frei zugänglich ist, müssen Sie Novell mitteilen, daß auch unverschlüsselte Paßwörter erlaubt sind.

Das TTS ist ab der Novell Version 2.2 und 3.11 aufwärts standardmäßig im System aktiviert. Aus Performancegründen sollte bei TTS Verwendung das SYS Volume auf einer anderen Platte als das Datenvolume sein. Außerdem muß auf dem SYS Volume auch immer genügend Platz zum Schreiben der TTS Datei sein.

Die zu überwachenden Datei werden mittels FLAG mit dem Attribut "T" markiert. Achtung: Als Transactional gekennzeichnete Dateien können nicht mehr gelöscht oder umbenannt werden. (Wichtig z.B. bei PACK!) Prinzipiell müssen alle zu einer dbf gehörenden Nebendateien als "T" gekennzeichnet werden, also nicht nur die DBF, sondern auch die FPT, CDX und eventuelle IDX Dateien.

 

Um von FoxPro aus auf das Novell TTS zugreifen zu können, benötigen Sie auf jeden Fall eine Library. Bei FoxPro/DOS ist sie von Haus aus dabei als NETWARE.PLB, bei FoxPro/WIN müssen Sie auf eine käufliche Library zurückgreifen. (Eine Aufstellung finden Sie am Ende des Artikels).

Novell unterstützt prinzipiell zwei Arten von TTS: Implizites und explizites TTS.

Implizit:

Explizit:

Durch das Datenbuffersystem von FoxPro kann es allerdings passieren, daß bei einer Transaktion auch Datensätze gesperrt werden, die physikalisch in der Nähe (genauer: innerhalb der Blockgrenze) liegen. Dies ist um so störender, weil eine TTS Sperre den physikalischen Zugriff auf die Datei unterbindet. D.h. Falls Sie mittels BROWSE durch die Datei blättern und dabei in den Bereich einer Transaktion kommen, verfällt FoxPro in einen Wartezustand, der nicht durch Drücken von ESC oder ähnlichem abgebrochen werden kann. Erst die Beendigung der Transaktion entläßt Sie wieder aus der Starre.

Trotzdem kann man das TTS System erfolgreich einsetzen, solange man die zwei Punkte beachtet

Unter FoxPro/DOS können Sie direkt die Novell Druckerqueues ansprechen, ohne daß diese erst über den Capture Befehl an einen LPT-Port angebunden sein müssen. So können Sie auf alle im Netzwerk vorhanden Drucker zugreifen:

Wichtig ist, daß die gesamte Anweisung OHNE Leerstellen angegeben wird. Bei manchen älteren NETX Shells funktionierte übrigens der \NB (No Banner) Schalter nicht. Da sie ja sowieso immer die neuesten Treiber verwenden, trifft sie das aber eh nicht....

Unter Windows können Sie die Druckqueues nicht mehr so einfach umstellen, hier geht alles über Einträge in der WIN.INI. Durch geeignete Routinen können Sie die installierten Drucker genauso abfragen wie die Anschlüsse, mit denen diese verbunden sind.

Um einen Drucker umzuleiten, ist folgende Routine brauchbar:

Und so nebenbei haben Sie gleich noch ein bißchen über die FOXTOOLS Library gelernt...


Netzwerkbefehle:

Die nachfolgende Auflistung erklärt die im Netzwerk verwendeten FoxPro Befehle.

Mit SET EXCLUSIVE wird festgelegt, ob Tabellen in einem Netzwerk für alleinigen oder gemeinsamen Zugriff von Benutzern zur Verfügung stehen.

Die Änderung der Einstellung von EXCLUSIVE ändert den Status von vorher geöffneten Tabellen nicht. Wenn z.B. eine Tabelle mit SET EXCLUSIVE ON geöffnet wurde und später SET EXCLUSIVE auf OFF gesetzt wird, bleibt die Tabelle weiterhin nur für alleinigen Zugriff geöffnet.

Der Standard für SET EXCLUSIVE ist ON.

ON

OFF

Anzeige von Änderungen bei Sätzen, die von anderen Benutzern im Netz vorgenommen wurden.

Tabellen können im Netz zur gemeinsamen Benutzung geöffnet werden. So können Sätze, die Sie sich gerade ansehen, gleichzeitig von einem anderen Benutzer im Netz bearbeitet werden. Benutzen Sie SET REFRESH, um festzulegen, ob geöffnete Datenblattfenster mit von anderen Benutzern vorgenommenen Änderungen aktualisiert werden sollen oder nicht.

SET REFRESH beeinflußt die Anzeige von Sätzen in einem Datenblattfenster, das mit BROWSE, CHANGE oder EDIT geöffnet wurde. Memofelder, die zur Bearbeitung in einem Datenblattfenster geöffnet sind, werden ebenfalls aktualisiert.

Mit SET REFRESH kann auch angegeben werden, wie oft lokal zwischengespeicherte Daten aktualisiert werden.

Der Standardwert ist 0, 5

<AusdrN1>

<AusdrN2>

Bestimmen, wie oft oder wie lange FoxPro nach einem erfolglosen Sperrversuch erneut versucht, eine Datei oder einen Satz zu sperren.

Eine Satz- oder Dateisperre ist nicht immer beim ersten Versuch erfolgreich. Häufig wurde ein Satz oder eine Datei von einem anderen Benutzer im Netzwerk gesperrt. Ist eine erste Satz- oder Dateisperre nicht erfolgreich, bestimmt SET REPROCESS, ob zusätzliche Sperrversuche an der Datei/am Satz ausgeführt werden.

Mit SET REPROCESS können Sie die Anzahl der zusätzlichen Sperrversuche oder die Dauer dieser Versuche angeben. Die Angabe einer ON ERROR-Routine beeinflußt die Reaktion auf einen erfolglosen Sperrversuch.

TO <AusdrN> [SECONDS]

Der numerische Ausdruck <AusdrN> gibt an, wie oft FoxPro nach einem erfolglosen Versuch einen erneuten Satzsperrversuch ausführt.

Der Standardwert ist 0.

0

-1

<AusdrN> > 0 [SECONDS]

TO AUTOMATIC

Mit SET LOCK können Sie die automatische Dateisperre aktivieren/deaktivieren. Bei der Ausführung von bestimmten Befehlen sperrt FoxPro normalerweise nicht die Dateien, wenn nur lesend auf eine Tabelle zugegriffen wird. Die folgende Liste enthält die Befehle, die einen Nur-Lese-Zugriff auf eine Tabelle durchführen:

Normalerweise kann die Tabelle während der Bearbeitung mit diesen Befehlen noch von anderen Anwendern im Netzwerk benutzt werden. Es ist daher möglich, daß die Tabelle während der Ausführung eines dieser Befehle geändert wird. Wenn Sie z.B. einen Bericht drucken und ein anderer Benutzer einen schon im Bericht enthaltenen Satz ändert, enthält Ihr Bericht dann nicht mehr die neuesten Daten und es können so Inkonsistenzen auftreten.

Der Standard ist SET LOCK OFF.

ON

OFF

Festlegen, ob mit LOCK() oder RLOCK() das gleichzeitige Sperren mehrerer Sätze möglich ist.

Ist eine Tabelle für gemeinsamen Zugriff im Netzwerk geöffnet, können Sie versuchen, mehr als einen Satz einer Tabelle zu sperren. Entsprechend der Einstellung von SET MULTILOCKS können Sie einen Sperrversuch an einem oder mehreren Sätzen vornehmen.

HINWEIS

Die Standardeinstellung ist SET MULTILOCKS OFF.

ON

OFF

Mit FLOCK() wird versucht, eine Tabelle zu sperren. Bei erfolgreichem Sperrversuch einer Tabelle wird wahr (.T.) zurückgegeben. Wenn die Datei oder ein Satz der Tabelle schon von einem anderen Benutzer gesperrt wurde, wird falsch (.F.) zurückgegeben. Es wird jedoch kein Fehler generiert. Aus diesem Grunde können Sie mit FLOCK( ) keine ON ERROR-Routine starten.

Bei erfolgreicher Dateisperre kann die Datei von dem Benutzer zum Lesen und Schreiben benutzt werden, der die Datei gesperrt hat. Für die anderen Benutzer im Netzwerk ist die Tabelle schreibgeschützt.

Eine Tabelle bleibt so lange gesperrt, bis die Sperrung durch den Benutzer, der die Sperrung verursacht hat, wieder aufgehoben wird. Bei Ausgabe von UNLOCK, Schließen der Tabelle oder Verlassen von FoxPro kann die Tabellensperrung wieder aufgehoben werden.

Standardmäßig versucht FLOCK( ) einmal, eine Datei zu sperren. Wenn automatisch ein erneuter Dateisperrversuch ausgeführt werden soll, falls der erste Versuch fehlschlägt, ist SET REPROCESS zu benutzen. Wenn ein Sperrversuch das erste Mal nicht erfolgreich war, wird mit SET REPROCESS die Anzahl der Sperrversuche und die Zeitdauer eines Sperrversuchs bestimmt

<AusdrN> | <AusdrZ>

Mit RLOCK() wird versucht, einen Datensatz oder eine Gruppe von Sätzen zu sperren. RLOCK() ist identisch mit LOCK().

Bei erfolgreicher Sperre wird wahr (.T.) zurückgegeben. Der Benutzer, der die Sperre verursacht hat, hat Lese- und Schreibzugriff auf die gesperrten Sätze. Alle anderen Benutzer im Netzwerk haben Nur-Lese-Zugriff auf die Sätze.

Die Ausführung von RLOCK() garantiert nicht, daß der/die Sperrversuch/e erfolgreich ist bzw. sind. Ein Satz, der schon von einem anderen Benutzer gesperrt wurde, kann nicht gesperrt werden. Ein Satz in einer von einem anderen Benutzer gesperrten Tabelle kann ebenfalls nicht gesperrt werden. Wenn die Sätze nicht gesperrt werden können, wird falsch (.F.) zurückgegeben.

Standardmäßig versucht RLOCK( ) einmal, einen Satz zu sperren. Benutzen Sie SET REPROCESS, um weitere Satzsperrversuche auszuführen, wenn der erste Versuch nicht erfolgreich war. SET REPROCESS bestimmt, wie oft oder wie lange nach einem ersten nicht erfolgreichen Versuch die Satzsperrversuche fortgesetzt werden.

<AusdrN> | <AusdrZ1>

<AusdrZ2>

Mit LOCK() können Sie versuchen, einen Satz oder eine Reihe von Sätzen einer Tabelle zu sperren. LOCK() ist identisch mit RLOCK().

Mit SYS(0) werden Rechnername und Rechnernummer als Zeichenkette zurückgegeben, wenn Sie FoxPro im Netz installiert haben. Rechnername und -nummer müssen zunächst von der Netzwerksoftware zugewiesen werden.

Unter Novell wird dies im Login-Script mittels der MACHINE Zuweisung erledigt:

Wenn Rechnername oder -nummer nicht zugewiesen oder die Netzwerkbenutzeroberfläche nicht geladen ist, gibt SYS(0) eine Zeichenkette zurück, die 15 Leerzeichen, ein Schraffurzeichen (#), gefolgt von einem weiteren Leerzeichen und 0 enthält.

Unter WindowsFWG und WindowsNT erhalten Sie den Namen ihres Arbeitsplatzes, die Raute und bei WinWG eine "0", bei WinNT "255".

Mit SYS(2011) wird der aktuelle Satz- oder Dateisperrstatus des aktuellen Arbeitsbereichs zurückgegeben. Im Gegensatz zu FLOCK(), LOCK() und RLOCK() führt SYS(2011) keinen Datei- oder Satzsperrversuch aus.

Die von SYS(2011) zurückgegebene Zeichenkette ist identisch mit der in der Statuszeile angezeigten Meldung (Exklusiv, Satz nicht gesperrt, Satz gesperrt ...). Aufpassen: Die zurückgegebenen Texte sind auch abhängig von der Sprachversion des verwendeten FoxPro Kerns. (Wichtig bei internationalen Programmen!)

SYS(2011) gibt "Exklusiv" nur an dem Rechner zurück, von dem aus die Tabelle exklusiv geöffnet wurde, und "Satz gesperrt" auch nur an dem Rechner, von dem aus der Satz gesperrt wurde.

UNLOCK hebt eine oder mehrere Satzsperre(n) oder eine Dateisperre der aktuellen Tabelle/.DBF, einer Tabelle in einem anderen Arbeitsbereich oder von Tabellen in allen Arbeitsbereichen auf. Satz- und Dateisperren bei Tabellen können nur von dem Benutzer wieder aufgehoben werden, der die Sperren gesetzt hat. Für alleinigen Zugriff geöffnete Tabellen können mit diesem Befehl nicht freigegeben werden.

Bei Verwendung von UNLOCK ohne zusätzliche Argumente wird eine Satzsperre (bzw. Sperren mehrerer Sätze) oder eine Dateisperre der Tabelle im aktuellen Arbeitsbereich aufgehoben.

IN <AusdrN> | <AusdrZ>

ALL

EXCLUSIVE

SHARED

NOUPDATE

Rückgabe von wahr (.T.), wenn Sie FoxPro/LAN, die Netzwerkversion von FoxPro, benutzen.

Alte Funktion, nur aus Kompatibilität vorhanden. Seit FoxPro 2.5 immer .T. (Unter FoxBase, FoxPro1 und FoxPro2 gab es gesonderte SingleUser und MultiUser Versionen)

Eine verbesserte NETWORK() Funktion könnten Sie so realisieren:

Diese Funktion macht sich zu nutze, daß eine Datei trotz Angabe von SHARED immer im Exklusiv Modus geöffnet wird, wenn keine Netzwerkunterstützung vorhanden ist (SHARE, NETX usw.)


 

Sonstige Informationen:

Bei der Erstellung dieser Unterlagen haben mir geholfen:

FoxPro Onlinehilfe (!)

Novell 3.x System Administrator Guide

FoxPro 2.5 Advanced Developers Handbook

MSDN (MicroSoft Developer Network CD

CompuServe

und natürlich ungezählte Stunden Try and Error....

Um weitergehende Informationen und Einstellungen im Netzwerk vorzunehmen, ist die Verwendung einer Zusatzlibrary fast unumgänglich.

Alle hier aufgeführten Zusatztools unterstützen jeweils FP/DOS und FP/WIN.

FPNet

NetLib

GPLib


Grundlagen der netzwerkfahigen Programmierung
(c)1994 Jurgen Wondzinski