Phantomsatz

Sonstiges (nicht kategorisierbar)

Moderator: Moderatoren

Antworten
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Phantomsatz

Beitrag von Manfred »

Hi,

mir ist gerade etwas sehr interessantes passiert. Ich sperre in einem Menue 2 DB. Das ist auch richtig so. Allerdings habe ich einen Denkfehler gemacht, von dem ich aber nicht 100% überzeugt bin, dass es einer war. In der 1.DB wird ein Satz gesucht. Wenn der gefunden wurde, wird in der 2.DB (Relation) die Ergänzung gesucht. Wenn in der 2.DB etwas gefunden wurde, ist alles klar, wenn aber nichts gefunden wurde, dann kommt jetzt der Fehler: Ich sperre pauschal beide DB. Einmal den gefundenen Satz und einmal wohl den Phantomsatz, weil in der 2.DB nichts gefunden wurde.
Wenn jetzt eine andere Station in der 2.DB etwas anhängen will, gibt es einen NetError().

Ich überlege die ganze Zeit, ob es richtig ist, dass es einen NetError() beim Appenden gibt. Ich dachte es wird generell ein leerer Satz angehängt und der wird automatisch gesperrt. Wenn nun die DB am Ende steht, weil nichts gefunden wurde, wie kann denn dann der Sperrvorgang der einen WS für den Appendvorgang der anderen WS einen Fehler erzeugen?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Jan »

Manfred,

bevor ich jetzt wieder irgendwas in Deine Worte interpretiere, was Du garnicht gemeint hast: Eine Verständnisfrage. Wenn ich das so lese hört sich das an, als wenn Du die beiden DBs getrennt "verarbeitest". Andererseits benutzt Du das Wort Relation. Kannst Du das bitte etwas präzisieren? Ist das nun eine DBSetRelation() bzw. SET RELATION oder eine manuelle Mitführung?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

Jan,

sehr gut. Was ich meine ist, dass ich eine Relation nachgebaut habe. Ich erwähne das nur, damit man sofort verstehe, was ich meine und tue. Also eigentlich nur ein Dbseek() mit eigener Hand zwischen den DB. Keine automatische Führung wie bei der Relation. Aber darauf kommt es nicht an. Es ist nur das Sperren eines Satzes, der gar nicht vorhanden ist, aber das Appenden an der Datenbank verhindert.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Martin Altmann »

Manfred,
und warum sperrst Du einen nicht vorhandenen Satz?
Sperre doch nicht beim Suchen (bzw. Finden), sondern erst beim Schreiben!
Und vor dem Schreiben vergleichst Du die Werte, die dort gespeichert sind, mit denen, die Du vor dem Bearbeiten gelesen hattest - ist da ein Unterschied, hat bereits jemand (zeitgleich) mit Dir geändert.
Oder Du sperrst halt den gefundenen Datensatz, bis eine Änderung zurückgeschrieben wird oder der Datensatzzeiger weiter bewegt wird - aber halt den gefundenen!

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14641
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 87 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Jan »

Manfred,

Danke für die Ergänzung. Im Pronzip kann in dem Fall nur unterschreiben, was Martin gesagt hat. Ich verstehe nicht ganz, wie Du einen nicht gefunden Satz sperren kannst bei einer manuellen Relation? Du schreibst ja selber, daß Du passend zum Ergebnis in der 1. DB in der 2. suchst. Aber wieso sperrst Du da, wenn nichts gefunden wird?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

Hi Martin,
Martin Altmann hat geschrieben:Manfred,
und warum sperrst Du einen nicht vorhandenen Satz?
Weil ich zu dem Zeitpunkt dachte, ich hätte es richtig gemacht. Dem war aber wohl nicht so.
Sperre doch nicht beim Suchen (bzw. Finden), sondern erst beim Schreiben!
Ich sperre, sobald der angezeigte Satz am Bildschirm geändert wird. Da weiß ich ganz genau, dass KEINER mir dazwischen funken kann, was bei dieser Anwendung durchaus passieren kann.
Und vor dem Schreiben vergleichst Du die Werte, die dort gespeichert sind, mit denen, die Du vor dem Bearbeiten gelesen hattest - ist da ein Unterschied, hat bereits jemand (zeitgleich) mit Dir geändert.
dazu bin ich im Moment zu faul. :(
Oder Du sperrst halt den gefundenen Datensatz, bis eine Änderung zurückgeschrieben wird oder der Datensatzzeiger weiter bewegt wird - aber halt den gefundenen!

Viele Grüße,
Martin
Das System klappt ja jetzt prima. Worauf ich hinaus wollte, war die Frage ob das überhaupt so logisch ist, das ein gesperrter nichtgefundener Satz ein Append verhindert. Wenn dem so ist, dann verstehe ich die Technik nicht wirklich. Bzw. warum kommt keine Fehlermeldung vom Laufzeitsystem, dass gar nichts zu sperren da ist?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Tom »

Tut mir leid, aber ich bekomme ums Verrecken keinen Laufzeitfehler, wenn ich den Phantomsatz einer Tabelle sperre und dann ein DbAppend() versuche. Übrigens auch nicht, wenn ich irgendeinen anderen Satz sperre.
Herzlich,
Tom
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

aha,

das ist ja interessant. Dann werde ich das Dingen nochmals in den Ursprungszustand versetzen und mit dem Debugger nachsehen, was denn dann bei mir passiert, dass es eben einen Fehler gibt.
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

Hi Tom,

also es sieht so aus. In der DB sind 31208 Datensätze. Der Phantomsatz ist der 31209 und ich kann exact im Debugger sehen, dass der gesperrt wird. Wenn ich dann im Debugger den Appendversuch ansehe, dann steht die DB genau auf dem 31209 und springt dann in die Errorsys um hier:

Code: Alles auswählen

CASE oError:genCode == XPP_ERR_APPENDLOCK .AND. ;
                       oError:canDefault
                       RETURN(.F.)
zu landen.

Sobald ich dann an der anderen WS das Ändernmenue verlasse und alle Sperren aufhebe, kann angehängt werden.
Watt nu?
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Martin Altmann »

Zeige doch mal die Zeile, in der Du sperrst...
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Phantomsatz

Beitrag von AUGE_OHR »

hi,
Manfred hat geschrieben:also es sieht so aus. In der DB sind 31208 Datensätze. Der Phantomsatz ist der 31209 und ich kann exact im Debugger sehen, dass der gesperrt wird.
Ich denke hier liegt ein Irrtum vor. Der "GhostRecord" ist LastRec()+1, was aber NICHT bedeutet das es physikalisch auch
die Recno() = LastRec()+1 ist. Vielmehr ist ein "GhostRecord" immer LastRec()+1.

Beispiel : Record = 99
A -> Goto LastRec()+1 -> Edit -> "GhostRec" = 100
B -> Append blank -> Record 100
A -> "GhostRec" -> 101
A -> Append blank -> Record 101

egal was "andere" mit der DBF machen ist der "GhostRec" immer LastRec()+1 was bedeutet er liegt
"ausserhalb" des Datenbank Bereich.
gruss by OHR
Jimmy
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

Meinst Du das hier Martin?

Code: Alles auswählen

********************************************************************************
/// <summary>
///  <para>
///     <bold>sperrt den aktuellen Satz der ZielDb</bold>
///  </para>
///  <para>
///     <bold>oZiel:</bold>wenn eine andere DB benutzt werden soll (default = self)
///  </para>
/// </summary>
METHOD datenbank:satzSperren(oZiel)
       LOCAL cDatum     := DToC((oZiel:nArea)->spdatum)
       LOCAL cPrg       := TRIM((oZiel:nArea)->spprg)
       LOCAL cUser      := TRIM((oZiel:nArea)->spuser)
       LOCAL cStation   := TRIM((oZiel:nArea)->spstation)
       LOCAL cZeit      := (oZiel:nArea)->spzeit
       LOCAL cText      := "ACHTUNG!!!" + CHR(13) +;
                           "Der Datensatz kann nicht gesperrt werden." + CRLF +;
                           "Er wurde an der Station: " + cStation + CRLF +;
                           "vom Benutzer: " + cUser + CRLF +;
                           "am: " + cDatum + CRLF +;
                           "um: " + cZeit  + CRLF +;
                           "vom Programm: " + cPrg + CRLF +;
                           "gesperrt." + CRLF + CRLF + ;
                           "SOLL DER VERSUCH WIEDERHOLT WERDEN?" + CRLF + CRLF +;
                           "Datenbank: "
       LOCAL cText2      := ""
       LOCAL lErfolg     := .T.
       LOCAL nVersuche   := 0
       LOCAL nSatzNummer

       MEMVAR oMessage
       MEMVAR oSysPara

       DEFAULT oZiel TO self

       nSatzNummer := (oZiel:nArea)->(Recno())
       DO WHILE .T.                                                             // Schleife dient nur dem zweck, falls der User es nochmals versuchen möchte, oder muß
          nVersuche++                                                           // es werden mehrere Versuche gegönnt
          IF (oZiel:nArea)->(DbRLock())                                         // Satz konnte gesperrt werden
             (oZiel:nArea)->spDatum   := Date()
             (oZiel:nArea)->spPrg     := oSysPara:cProgrammName
             (oZiel:nArea)->spstation := oSysPara:cNetName
             (oZiel:nArea)->spuser    := oSysPara:cUserName
             (oZiel:nArea)->spzeit    := Time()
//             (oZiel:nArea)->(DbSkip(0))                                         // hier muß auf jeden FAll ein Dbskip(0) hin. (25.08.2008)
             (oZiel:nArea)->(DbGoto(nSatzNummer))                               // das gibt sonst Murks nach einem                       .
             EXIT
          ENDIF
          IF nVersuche > 2                       // es wurde mehrmals versucht. Wie of muß die Erfahrung mit sich bringen
             cText2 = Upper((oZiel:nArea)->(Alias())) + CHR(13)+;
                      "Sperrversuche: " + Alltrim(Str(nVersuche))
             IF oMessage:anzeigen(cText + cText2,.T.,"J")
                LOOP
             ELSE
                lErfolg := .F.
                EXIT
             ENDIF
          ENDIF
       ENDDO
RETURN lErfolg
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16502
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Phantomsatz

Beitrag von Martin Altmann »

Yup!
Du rufst DbRlock() ohne Parameter auf - also wird der aktuelle Datensatz gesperrt! Hast Du denn davor einen Append blank gemacht?
Was passiert, wenn Du die Datensatznummer, die Du sperren willst, explizit angibst?

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 21165
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel
Hat sich bedankt: 206 Mal
Danksagung erhalten: 67 Mal

Re: Phantomsatz

Beitrag von Manfred »

Ja,

richtig, so soll es ja sein. Das ist nur der Sperrmechanismus. Ein Append sieht so aus:

Code: Alles auswählen

********************************************************************************
METHOD datenbank:satzNeu(oZiel,lSchreiben)
       LOCAL lErfolg    := .T.

       MEMVAR oMessage
       MEMVAR oSysPara

       DO WHILE .T.
          (oZiel:nArea)->(DbAppend())
          IF NetErr()                                                           // es wurde ein Fehler zurückgegeben
// geht das evtl. noch eleganter?
             IF oMessage:anzeigen("ACHTUNG!!! Es konnte kein neuer Datensatz an die Datei: " + ::cDbank + ;
                                  "angehängt werden. Nochmal versuchen?",.T.,"J")
                LOOP
             ENDIF
             lErfolg := .F.
          ENDIF
          (oZiel:nArea)->spdatum   := DATE()
          (oZiel:nArea)->spprg     := oSysPara:cProgrammName
          (oZiel:nArea)->spuser    := oSysPara:cUserName
          (oZiel:nArea)->spstation := oSysPara:cNetName
          (oZiel:nArea)->spzeit    := Time()
          IF lSchreiben
             (oZiel:nArea)->(DbCommit())
          ENDIF
          EXIT
       ENDDO .T.
RETURN lErfolg
Gruß Manfred
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.
großer Fan des Xbaseentwicklerwiki https://wiki.xbaseentwickler.de/index.p ... Hauptseite
Doof kann man sein, man muß sich nur zu helfen wissen!!
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Phantomsatz

Beitrag von AUGE_OHR »

Tom hat geschrieben:Tut mir leid, aber ich bekomme ums Verrecken keinen Laufzeitfehler, wenn ich den Phantomsatz einer Tabelle sperre und dann ein DbAppend() versuche. Übrigens auch nicht, wenn ich irgendeinen anderen Satz sperre.
aber ich jetzt mit der v335 und FOXCDX ...

Code: Alles auswählen

GOTO LASTREC()+1
nRec := RECNO()
IF RLOCK
    REPLACE
    UNLOCK -> crash  
auch wenn ich es mit DbrLock(nRec) versuche bekomme ich bei DbrUnlock(nRec) einen Fehler ... :-k

hm ... sehr merkwürdig ... das kann ja nicht sein ...
ALIAS ist richtig und Errorlog sagt mir auch das sonst alles klar ist ... und trotzdem ...

achso, weil das UNLOCK ja nicht ging, dachte mir lass es doch einfach erstmal ... bis zum DbAppend() -> crash :shock:
gruss by OHR
Jimmy
Antworten