Announcement

Collapse
No announcement yet.

SHARE FEHLER

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SHARE FEHLER

    Ich habe ein Programm, daß 4 Tables hat. Je zwei dienen als Table für alle
    User und zwei sind private Tables.

    Alle Tables haben nur drei Felder: Integer, String und Memo. Indiziert ist
    auf Integer als Primärindex, keine Sekundärindizes. Kein Autoinc.

    Mein Testprogramm soll 10000 Sätze an die privaten Tables anhängen, der
    Integer wird dabei aus der ALL-Table geholt (Write lock setzen, warten bis
    Write lock ging, dann last, letzten Integer lesen, append, Integer:=Wert+1,
    posten, write lock freigeben). Diesen Integer trage ich in die User-DB ein.
    Das mache ich 10000 mal und fertig.

    Die IDs sind dann "registriert" und abgehakt und ein anderer Benutzer kann
    die nicht mehr anfordern (sondern bekommt die nächste freie ID).

    Dann "übertrage" ich die 10000 IDs in die All-DB indem ich Satz für Satz
    die User-DB durchgehe, die ID hole, den Satz mit dieser ID in der ALL-DB
    finde und z.B. im String-Feld der ALL-DB irgendwas eintrage.

    Dann mache ich emptytable mit den user-db (die sind übrigens exklusiv und
    natürlich hat jedes Programm seine eigene User-DB).

    Jetzt zum Problem:
    Mache ich das lokal oder auf einem NT-Server oder auf NOVELL geht das, so
    lange ich das von VERSCHIEDENEN STATIONEN (!) aus mache.

    Starte ich beide Programme auf EINEM Rechner (egal wo ich Daten ablege),
    dann macht es bei EMPTYTABLE (!!!!) Rumms mit besagter Fehlermeldung. Mehr
    gibt es nicht zu der Meldung, mit oder ohne Delphi, mit eingeschalteten
    Exceptions.

    Nehme ich die Memo-Felder raus, geht es sofort mit 10000. Mit 2000 treten
    die Probleme trotz Memo auch (noch?) nicht auf.

    Delphi 4 SP3, NT SP4.

    Abgerüstetes Testprogramm mit Quellen vorhanden.

    Hat jemand Ideen?

    Mfg

    Jens Hoyer

    [email protected]

  • #2
    Hallo,

    ich vermute einmal, das eine Paradox-Datenbank (..<i>AUTOINC, User-DB</i>...) verwendet und auf diese über eine 32-Bit-Version der BDE zugegriffen wird. Trotzdem habe ich noch weitere Fragen:<br>
    1. Wie sieht der Fehlermeldungsdialog <i>SHARE FEHLER</i> aus (d.h. stammt er vom Programm oder kommt er direkt von Win32)?<br>
    2. Wird in der Anwendung eine SELECT-Abfrage via TQuery verwendet?<br>
    3. Wie wird im Programm die Session-Eigenschaft <b>PrivateDir</b> konfiguriert?<br>
    4. Verschwindet die Fehlermeldung, wenn für die BDE die Eigenschaft <b>LOCAL SHARE</b> aktiviert wird?<br>
    5. Verwenden alle Clients tatsächlich einen gemeinsamen (identischen) Wert für die BDE-Eigenschaft <b>NET DIR</b>? <br>
    6. Tauchen beim Zugriff auf große Memo-Daten temporäre Tabellen im PrivateDir-Verzeichnis auf?<br>

    Wenn ich die Stichwörter <i>Exclusiver Tabellenzugriff</i> und <i>Zugriff vom lokalen Rechner aus</i> höre, fällt mir spontan eine der BDE-Performanceoptimierungen ein (Einsparen von Dateisperren). Werden dann allerdings mehrere Programminstanzen auf dem gleichen Rechner gestartet, die alle das gleiche <b>PrivateDir</b> verwenden, könne das geschilderte Problem auftreten

    Comment


    • #3
      Ich vermute einmal, das eine Paradox-Datenbank (..AUTOINC, User-DB...)
      verwendet und auf diese über eine 32-Bit-Version der BDE zugegriffen
      wird.

      <b>Das ist richtig!</b>

      1. Wie sieht der Fehlermeldungsdialog SHARE FEHLER aus (d.h. stammt er
      vom Programm oder kommt er direkt von Win32)?

      <b>Der Fehler scheint aus dem Programm zu stammen (roter Kreis mit
      weißem Kreuz, Text SHARE FEHLER in ausschließlichen Großbuchstaben,
      kein typisches Win32-Fehlerfenster, aber auch nicht wie normale
      Delphi-Execptions: die kommen dann später noch).</b>

      2. Wird in der Anwendung eine SELECT-Abfrage via TQuery verwendet?

      <b>nein; TSession,TDataSource,TTable</b>


      3. Wie wird im Programm die Session-Eigenschaft PrivateDir
      konfiguriert?

      <b>Überhaupt nicht, d.h. bleibt auf Default aus der BDE, muß ich das
      denn? Die Tabellen die die Sharing-Probleme bereiten liegen zwar in
      dem selben Verzeichnis heißen aber unterschiedlich (Jede Anwendung
      bekommt einen eindeutigen Tabellennamen zugeordnet). Wenn es sich
      vermeiden läßt, möchte ich auch nicht unbedingt weitere
      Unterverzeichnisse anlegen müssen.
      Habe versucht:
      a) jeder Anwendung ein eigenes PrivatDir => hat nicht geholfen
      b) die privaten Tabellen auch wirklich im PrivatDir abgelegt => hat
      nicht geholfen.</b>


      4. Verschwindet die Fehlermeldung, wenn für die BDE die Eigenschaft
      LOCAL SHARE aktiviert wird?

      <b>leider nein</b>

      5. Verwenden alle Clients tatsächlich einen gemeinsamen (identischen)
      Wert für die BDE-Eigenschaft NET DIR?

      <b>Ja! Getestet mit NET DIR auf Server bzw. auch lokal.</b>

      6. Tauchen beim Zugriff auf große Memo-Daten temporäre Tabellen im
      PrivateDir-Verzeichnis auf?
      <b>nein</b>

      Wenn ich die Stichwörter Exclusiver Tabellenzugriff und Zugriff vom
      lokalen Rechner aus höre, fällt mir spontan eine der
      BDE-Performanceoptimierungen ein (Einsparen von Dateisperren). Werden
      dann allerdings mehrere Programminstanzen auf dem gleichen Rechner
      gestartet, die alle das gleiche PrivateDir verwenden, könne das
      geschilderte Problem auftreten

      Comment


      • #4
        Hallo,

        sehr merkwürdig - es scheint so, als ob zur Ursacheneingrenzung nur die Versuch+Irrtum-Methode am erfolgversprechensten ist. Es wäre auch interessant, an exakt welcher Stelle in der VCL der Fehler entsteht (Projekt mit Debug-Info incl. für die VCL-Sourcen compilieren):

        1. Beseitigt das Erhöhen der Werte verschiedenen BDE-Parameter (siehe BDE-Verwaltung -> Konfiguration -> Sytem -> INIT) das Problem (MEMSIZE, SHAREDMEMSIZE, MAXFILEHANDLES)?

        2. Was passiert, wenn die Tabellen nicht bereits in der IDE, sondern erst zur Laufzeit im Programm geöffnet werden. Tritt der Fehler auch dann immer noch auf, wenn <b>keine</b> Tabelle in der IDE beim Compilieren aktiv ist (nicht nur die temp./benutzerbezogenen)?

        3. Wann werden die Tabellen mit Exclusiv-Rechten geöffnet? Erst unmittelbar vor dem Aufruf von EmptyTable oder bereits von Anfang an via Objektinspektor? Verschwindet der Fehler, wenn Exclusiv erst zur Laufzeit aktiviert wird? Sind noch andere, feststehende Tabellen zu diesem Zeitpunkt exclusiv geöffnet?

        4. Um ein NT-Problem auszuschliessen, kann der folgende Versuch gemacht werden:<br>
        a) Das Programm öffnet eine Test-Tabelle und schliesst diese wieder.<br>
        b) Kann diese (geschlossene) Tabelle über den Explorer als Datei von Hand gelöscht werden, wenn die Anwendung noch läuft?

        5. Sollte alles nichts helfen, kann ich nur noch anbieten, einen Blick auf das vorbereitete Testprogramm zu werfen (eMail an <i>[email protected]</i>).
        &#10

        Comment


        • #5
          sehr merkwürdig - es scheint so, als ob zur Ursacheneingrenzung nur
          die Versuch+Irrtum-Methode am erfolgversprechensten ist. Es wäre auch
          interessant, an exakt welcher Stelle in der VCL der Fehler entsteht
          (Projekt mit Debug-Info incl. für die VCL-Sourcen compilieren):

          <b>Komt man leider auch nur bis zur Stelle dbiEmptyTable in der Unit
          dbTables: liefert ErrorCode 11058=SHARE-Fehler</b>

          1. Beseitigt das Erhöhen der Werte verschiedenen BDE-Parameter (siehe
          BDE-Verwaltung -> Konfiguration -> Sytem -> INIT) das Problem
          (MEMSIZE, SHAREDMEMSIZE, MAXFILEHANDLES)?

          <b>Ich stehe, glaube ich, auch schon am oberen Limit MEMSIZE=16,
          SHAREDMEMSIZE=4096, MAXFILEHANDLES=2048</b>

          2. Was passiert, wenn die Tabellen nicht bereits in der IDE, sondern
          erst zur Laufzeit im Programm geöffnet werden. Tritt der Fehler auch
          dann immer noch auf, wenn keine Tabelle in der IDE beim Compilieren
          aktiv ist (nicht nur die temp./benutzerbezogenen)?

          <b>-die Tabellen werden erst zur Laufzeit erstellt und aktiviert;
          ebenso die zugehörigen Objekte TSession,TDataSource und TTable
          -die IDE ist gar nicht aktiv (2x EXE): => Fehler tritt auch auf</b>

          3. Wann werden die Tabellen mit Exclusiv-Rechten geöffnet? Erst
          unmittelbar vor dem Aufruf von EmptyTable oder bereits von Anfang an
          via Objektinspektor? Verschwindet der Fehler, wenn Exclusiv erst zur
          Laufzeit aktiviert wird? Sind noch andere, feststehende Tabellen zu
          diesem Zeitpunkt exclusiv geöffnet?

          <b>Die Tabellen werden zur Laufzeit exclusive erzeugt</b>

          4. Um ein NT-Problem auszuschliessen, kann der folgende Versuch
          gemacht werden:
          a) Das Programm öffnet eine Test-Tabelle und schliesst diese wieder.
          b) Kann diese (geschlossene) Tabelle über den Explorer als Datei von
          Hand gelöscht werden, wenn die Anwendung noch läuft?
          <b>Vollkommen problemlos! Läßt sich löschen, wieder erzeugen
          usw...</b>

          5. Sollte alles nichts helfen, kann ich nur noch anbieten, einen Blick
          auf das vorbereitete Testprogramm zu werfen .

          </b>Soeben getan. Und: DANKE.</b&gt

          Comment


          • #6
            Hallo Jens,

            ich werde erst heute Abend dazu kommen, die eMail auszulesen. Wenn der Fehler beim Aufruf von <b>dbiEmptyTable</b> kommt, würde ich doch noch einmal 2 Tests machen:<br>
            1. MEMSIZE=64 (16..205 MB zulässig); SHAREDMEMSIZE=16384 (kByte)<br>
            2. SHAREDMEMLOCATION: Adress-Wert ändern (siehe BDE-Hilfe: <i>Vorgabewert (für Windows NT): 0x6BDE0000; Kleinster Wert (für Windows NT): 0x10000000; Größter Wert (für Windows NT): 0x7F000000 </i>

            Comment


            • #7
              1. MEMSIZE=64 (16..205 MB zulässig); SHAREDMEMSIZE=16384 (kByte)

              <b>Hat beides nicht geholfen</b>

              2. SHAREDMEMLOCATION: Adress-Wert ändern (siehe BDE-Hilfe: Vorgabewert
              (für Windows NT): 0x6BDE0000; Kleinster Wert (für Windows NT):
              0x10000000; Größter Wert (für Windows NT): 0x7F000000 )

              <b>Habe mangels besseren Wissens einige Adressen durchprobiert: der
              Fehler bleibt und manchmal kommt noch hinzu, daß die 2. Anwendung die
              gemeinsam genutzten Tabellen überhaupt nicht öffnen kann</b&gt

              Comment


              • #8
                Hallo,

                ich habe mir das Testprogramm angeschaut und bin zu folgenden Ergebnissen gekommen:<br>
                - 1. Programminstanz: Start mit <b>C:\Ablage\TestCADdy2.exe</b> <br>
                - 2. Programminstanz: Start mit <b>C:\Ablage\TestCADdy2.exe U</b> <br>
                - Beide Programme legen Datenbanktabelle auf E:\ an <br>
                - Test mit 2000 Datensätzen: Aufladen -> Übertragen -> Leeren -> keine Fehlermeldung <br>
                - Test mit 6000 (erste Instanz) und 7000 (zweite Instanz) Datensätzen: Aufladen -> Übertragen -> SHARE-Fehler bereits beim Aufladen (also kann es nicht die ISAPI-Funktion für das Leeren der Tabelle sein), nachdem die Anzeige der übertragenen Datensätze gleich dem Wert der aufgeladen Datensätze ist. Die User DB der ersten Instanz kann geleert werden, die zweite Instanz jedoch nicht (SHARE Fehler). Der SHARE Fehler in der zweiten Instanz bleibt auch dann, wenn die erste Instanz geschlossen wird.

                In den Funktionen <i>Aufladen</i> und <i>Übertragen</i> wird die private Methode WaitForLockTable(TableAllDBID,ltWriteLock) aufgerufen. Dort wird bis zu 500 Mal versucht, eine Tabellensperre zu setzten, wobei ich zusätzlich über <b>iCollisionCnt</b> die Anzahl
                der Kollisionen ermittle:
                <pre>
                procedure TForm1.WaitForLockTable(ATable: TTable; LockType: TLockType);
                var i : integer;
                begin
                for i:=1 to 500 do begin
                try
                ATable.LockTable(LockType);
                if i > 1 then
                Inc(iCollisionCnt);
                break;
                except
                Sleep(150);
                if i=500 then raise; // Ende der Fahnenstange
                end;
                end;
                end;
                </pre>

                Die TTable-Methode <b>LockTable</b> wird in der Unit <i>DBTables</i> über den Aufruf der IDAPI-Funktion <b>DbiAcqTableLock</b> implementiert. Und in der BDE.HLP steht zu dieser Funktion der folgende Satz: <i>Redundant locks can be acquired on the table. For each lock acquired, a separate call to DbiRelTableLock is required to release it.</i> In den <b>BDE-Limits</b> (siehe <i>http://www.borland.com/devsupport/bde/ti_list/TI2751.html</i>)
                wird auf eine maximale Obergrenze für die Tabellensperren hingewiesen. Es sieht so aus, also ob für jeden Aufruf von <b>LockTable</b> ein <b>UnlockTable</b>-Aufruf notwendig ist.

                Bei 2 x 7000 Datensätze erhalte ich beim Aufladen 159 Kollisionen (beide Anwendungen liefern die gleiche Zahl zurück). Nach jedem Aufladen/Übertragen <b>schliesse und öffne ich dann die Tabellen</b> (damit alle Sperren automatisch entfernt werden). Nun kann ich 7000 Datensätze verarbeiten, <b>ohne</b> auf den SHARE-Fehler zu stossen!

                Problem gelöst

                Comment


                • #9
                  Leider nein!

                  Daß beide Instanzen die gleiche Anzahl von Kollisionen liefern ist
                  normal und richtig, denn nur diese beiden Instanzen konkurrieren
                  miteinander, wobei ich aber 159 von 7000, also nicht einmal 3%, für
                  eine verträgliche Größe halte.

                  Ein nicht gelungenes LockTable kann leider nicht durch ein UnlockTable
                  repariert werden:
                  Exception "Objekt nicht gesperrt"

                  Das Schließen der Tabellen (und damit verbundenes Abmelden des
                  Benutzers von der Datenbank) ist, denke ich für MultiUserSysteme nicht
                  tragbar, da genau in diesem Moment eine andere Instanz daher kommen
                  könnte und, da sie ja nun der einzige Benutzer der Tabelle ist,
                  DeleteTable ausführt.

                  Ich bin durchaus auch der Meinung, daß am Locking irgendwas faul ist,
                  weil: befragt man die Table mit DbiIsTableLocked so liefert dies nur
                  True wenn meine eigene Instanz die Sperrung errichtet hat. Hat eine
                  andere Anwendung die Sperre errichtet, behauptet DbiIsTableLocked
                  eiskalt: die Table ist voll verfügbar. Ich denke das ist nicht ganz
                  richtig so, und läuft vielleicht auf den selben Bug hinaus, der noch
                  keinem aufgefallen sein sollte? Nee, ich denke dafür ist die
                  Aufgabenstellung zu gewöhnlich.

                  Was die Obergrenzen der Sperrungen anbetrifft so sind mir diese voll
                  bewußt, im Normalfall ist pro Instance immer nur eine Sperrung aktiv
                  und wird auch kürzest möglich wieder freigegeben. Und bisher spreche
                  ich hier von nur zwei Instanzen. Auch in dem Testprogramm hätten sich
                  die Sperrungen nicht aufsummieren dürfen.

                  Irgendwo läßt die BDE wohl noch weitere Informationen zum
                  Tabellenstatus. Eventuell hilft auch folgende Fehlerbeschreibung, die
                  auch mit Sperrungen zu tun hat. Stürzt eine BDE-Application ab oder
                  wird sie aus der IDE gewaltsam (Strg-F2) beendet, dann bleiben die
                  Tabellen irgendwie gesperrt. Das nächste Öffnen liefert dann die
                  Exception "Tabelle ist in Benutzung durch ...". Hierbei gilt zu
                  bemerken, daß es sich um ganz normale BDE-Applicatiopnen handelt, d.h.
                  SingleUser, kein Locking usw. . Eine weiter Information, die ich noch
                  beisteuern kann, ist folgende. Wenn die Datenbanken auf einem Server
                  abgelegt werden und man dann beobachtet was in dem
                  DataSource-Verzeichnis so abläuft, so staunt man nicht schlecht, wie
                  viele temporäre Datenbanken die BDE dort benutzt.

                  Zu Ihrem Quelltext: So ganz verstehe ich nicht, was Sie mit dem
                  Counter machen. Sie zählen die Sperrungen, da NACH der ersten Sperrung
                  erfolgreich sind? Wozu?

                  Ich bin für jede weiter Idee zu meinem Problem dankbar..

                  Comment


                  • #10
                    Hallo,

                    auf was bezieht sich Ihre Anwort <i>Leider nein!</i>: Tritt bei Ihnen der Fehler trotzdem noch auf oder ist der Weg an sich ungeeignet?

                    Mein Counter <i>iCollisionCnt</i> zählt nur die <b>nicht sofort erfolgeichen</b> Lock-Anforderungen. Immer dann, wenn die Schleifenvariable größer 1 ist, ist mindestens ein LockTable-Aufruf fehlgeschlagen, so daß nach 150ms ein weiterer Versuch unternommen wird. In iCollisionCnt steht am Ende die Anzahl der <b>Fehlversuche</b>.

                    <i>Was die Obergrenzen der Sperrungen anbetrifft so sind mir diese voll bewußt, im Normalfall ist pro Instance immer nur eine Sperrung aktiv und wird auch kürzest möglich wieder freigegeben. Und bisher spreche ich hier von nur zwei Instanzen. Auch in dem Testprogramm hätten sich die Sperrungen nicht aufsummieren dürfen. </i>

                    Nein - das glaube ich nicht. Offensichtlich gilt die Obergrenze von <b>256</b> (??...aus meinem Gedächtnis) Locks auch für Lockversuche auf diese Tabelle. Bereits nach dem Aufladen waren davon <b>159</b> Locks verbraucht. Wenn ein nicht gelungenes LockTable nicht durch ein UnlockTable repariert werden kann, bleibt wohl nichts anderes übrig, als die Tabellen kurzzeitig zu schliessen (denn dann lehrt die BDE implizit alle Lock-Puffer für diese Tabelle).

                    Da der Effekt nur dann auftritt, wenn zwei Programminstanzen auf dem gleichen Rechner ausgeführt werden, gehe ich davon aus, das die BDE intern in diesem Sonderfall eine "Optimierung" durchführt, die leider diese Nebenwirkungen zeigt

                    Comment


                    • #11
                      "Leider Nein" bezieht sich auf Ihre letzte Frage, nämlich ob das
                      Problem damit gelöst ist.

                      Und ich denke, daß es das nicht ist. Denn das Schließen und Öffnen der
                      Table ist zwar ein Workaround, aber eigentlich keine Lösung.

                      Zu Ihrem Counter:
                      Ich denke, daß Sie sich irren. Der Counter wird nur hochgezählt, wenn
                      der n. Versuch klappt, wobei n>1 sein muß. Da immer beim Locken eine
                      exception auftritt wenn das Locken nicht ging, kommen Sie gar nicht in
                      den Genuß, zählen zu können, wie oft das Locken nicht ging. Der
                      Counter zeigt nur, wie oft das Locken erst ab dem zweiten Versuch
                      ging - nicht wie oft der einzelne Versuch wiederholt werden musste. Um
                      das zu Summieren hätten Sie den Counter in den Except-Block eintragen
                      müssen. Sie haben nur gezählt, wieoft es ging wenn es vorher schonmal
                      nicht ging.

                      Glauben Sie mir? Dann sollten Sie jetzt weiterlesen:
                      Und als ich das jetzt gerade mit Zahlen belegen wollte und Ihnen
                      schreiben wollte, wie hoch der Counter zählt, wenn man die Exceptions
                      zählt, da habe ich (und ich bin Baff) festgestellt, daß beide Counter
                      (Ihrer und meiner im Except-Block) identische Werte zeigen!!!! Nicht
                      daß ich Ihrem Counter nicht traue, aber daß mein Counter um -1
                      versetzt identische Werte zeigt, überrascht mich sehr. Denn ich zähle
                      die Anzahl der Exceptions. Und wenn beide Werte gleich groß sind
                      (fast) würde das heißen, daß jeder zweite Versuch <b>immer</b> klappt.
                      Und <b>daran</b> glaube ich nun wirklich nicht.

                      Also ich bleibe da dran! Aber ich bin etws mutlos... Erstens habe ich
                      sicher keinen Einfluß auf die Reparatur dieses Sonderfalls eines
                      BDE-Einsatzes und zweitens brauche ich eine Lösung, und da werde ich
                      wohl vorerst verhindern, daß ein Anwender den gleichen Datenbestand
                      zweimal auf dem selben Rechner öffnet.
                      Schade. Wäre genial gewesen. Trotzdem: Ich werde am Wochenende noch
                      ein bißchen daran drehen

                      Comment


                      • #12
                        Hallo,

                        so war meine Antwort <i>Mein Counter iCollisionCnt zählt nur die nicht sofort erfolgeichen Lock-Anforderungen</i> ja auch gemeint.
                        Das Ihr Counter um -1 niedrigere Werte zeigt, überrascht mich nicht. Es ist doch egal, ob oberhalb des Aufrufs von <b>ATable.LockTable(LockType);</b> (die Zählung vor dem Aufruf berücksichtigt dann auch die fehlgeschlagenen Versuche) gezählt wird oder darunter. Wenn die Sperre gesetzt werden kann, muß mein Counter automatisch einen Wert höher sein als der im Exception-Block (denn der letzte Versuch ist ja erfolgreich gewesen, so daß keine Exception ausgelöst wird).

                        Falls ein Anwender mehrere Programminstanzen auf dem gleichen Rechner starten soll, würde ich folgendes machen: <br>
                        1. Prüfen, ob bereits eine Programminstanz läuft. <br>
                        2. Wenn ja, einen Win32-<b>Semaphore</b> (oder <b>MUTEX</b>) anfordern und den Zugriff auf die Tabelle so synchronisieren. Somit müssen die lokalen Tabellen <b>nicht</b> mehr über die BDE gesperrt werden, so daß auch keine Locks hochlaufen können.

                        P.S. Das so häufige Sperren kompletter Tabellen ist nicht der Normalfall - auch in einer Mehrbenutzerumgebung werden meistens nur die Datensätze gesperrt

                        Comment


                        • #13
                          Hallo Jens,

                          ich habe einige zusätzliche Versuche gemacht, wobei sich allerdings meine erste Vermutung (die BDE sperrt in diesem Sonderfall nach dem <i>Wechselschalterprinzip</i>) leider <b>nicht</b> bestätigt hat. Hier meine neuen Zahlen:
                          <pre>
                          procedure TForm1.WaitForLockTable(ATable: TTable; LockType: TLockType);
                          var i : integer;
                          begin
                          for i:=1 to 500 do begin
                          try
                          Inc(iCallCnt);
                          ATable.LockTable(LockType);
                          if i > 1 then
                          Inc(iCollisionCnt);
                          break;
                          except
                          Inc(iExceptionCnt);
                          if bSecondUser then
                          Sleep(175)
                          else
                          Sleep(150);
                          if i=500 then raise; // Ende der Fahnenstange
                          end;
                          end;
                          end;
                          </pre>

                          <table border="0">
                          <tr>
                          <td><font color="#000080" face="Arial">Anzahl der Datensätze</font></td>
                          <td><font color="#000080" face="Arial">iCollisionCnt </font></td>
                          <td><font color="#000080" face="Arial">iExceptionCnt </font></td>
                          <td><font color="#000080" face="Arial">iCallCnt </font></td>
                          <td><font color="#000080" face="Arial">SHARE-Fehler </font></td>
                          </tr>
                          <tr>
                          <td>Aufladen von 2000 (1. Instanz) </td>
                          <td>42</td>
                          <td>82</td>
                          <td>2082</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Aufladen von 2000 (2. Instanz)</td>
                          <td>42</td>
                          <td>99</td>
                          <td>2099</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Übertragen von 2000 (1. Instanz) </td>
                          <td>36</td>
                          <td>92</td>
                          <td>2092</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Übertragen von 2000 (2. Instanz) </td>
                          <td>37</td>
                          <td>107</td>
                          <td>2107</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          </tr>
                          <tr>
                          <td>Aufladen von 7000 (1. Instanz)</td>
                          <td>43</td>
                          <td>169</td>
                          <td>7169</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Aufladen von 7000 (2. Instanz)</td>
                          <td>42</td>
                          <td>167</td>
                          <td>7167</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Übertragen von 7000 (1. Instanz)</td>
                          <td>77</td>
                          <td>239</td>
                          <td>7239</td>
                          <td>Ja</td>
                          </tr>
                          <tr>
                          <td>Übertragen von 7000 (2. Instanz)</td>
                          <td>77</td>
                          <td>252</td>
                          <td>7252</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td><font color="#000080">(Tabellen werden gelösch, <br>
                          zweite Instanz verwenden einen<br>
                          anderen Wert für Sleep)</font></td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          <td>&nbsp;</td>
                          </tr>
                          <tr>
                          <td>Aufladen von 2000 (1. Instanz) </td>
                          <td>20</td>
                          <td>47</td>
                          <td>2047</td>
                          <td>Nein</td>
                          </tr>
                          <tr>
                          <td>Aufladen von 2000 (2. Instanz) </td>
                          <td>19</td>
                          <td>56</td>
                          <td>2056</td>
                          <td>Nein</td>
                          </tr>
                          </table&gt

                          Comment


                          • #14
                            Hallo Herr Kosch,

                            fehlt mir da jetzt was bei der Tabelle?? Oder verstehe ich nur nicht,
                            was Sie mir damit sagen wollen.

                            Unabhängig davon habe ich das sofort probiert und den Sleep zwischen
                            10 und 250 zufällig ermitteln lassen. Jetzt habe ich zwar nur bei
                            einer Instanz den Share-Fehler, aber was heißt das...??

                            Comment


                            • #15
                              Hallo Jens,

                              äh - da war ich wohl bei meiner Argumentation zu schreibfaul gewesen. Was ich sage wollte ist das: Zuerst dachte ich, das die BDE in diesem Sonderfall (2 Instanzen auf dem gleichen Rechner, nur Zugriff auf lokale Tabellen) intern ein <i>Win32-Sperrobjekt</i> verwendet, und beiden Instanzen <b>abwechselnd</b> den Zugriff auf die Tabelle einräumt. Allerdings müssten dann die Zahlen für iCollisionCnt und iExceptionCnt symetrisch in Beziehung stehen - was aber leider nicht der Fall ist. Mit wachsender Tabellengröße wird das Verhältnis schlechter. Auch das Variieren der <b>Sleep</b>-Zeit kann nicht zur Erklärung dieses Effekts (SHARE Fehler) beitragen.

                              Somit gehe ich davon aus, das in diesem Sonderfall eine Anomalie (um nicht Bug zu sagen) der BDE vorliegt. Man muß also als Workaround entweder<br>
                              a) die Tabellen kurzeitig schließen, oder <br>
                              b) intern im Programm verhindern, das sich 2 lokale Instanzen in die Query kommen (Stichwort <i>Win32-Sperrobjekte</i>).
                              &#10

                              Comment

                              Working...
                              X