[Allegro] Mysteriöse Variable
Thomas Berger
ThB at Gymel.com
Do Mai 3 11:19:43 CEST 2012
Lieber Herr Eversberg,
>> Es ist moeglicherweise etwas ineffizient, direkt nach einem
>> (evtl. impliziten) "get first" noch ein "get edit" zu geben
>> !!!
>> (ich darf doch davon ausgehen, dass "get edit" zuerst den
>> Satz sperrt, ihn dann noch einmal frisch einliest und damit
>> bereits evtl. vorher im Arbeitsspeicher unternommene Aenderungen
>> zunichte macht?),
>> !!!
> Dürfen Sie. Da wird eben gerade auch noch was dran gefeilt. (Nicht
> "noch einmal", sondern "erst dann")
nach einem find (das ja implizit den ersten Satz laedt) bzw.
nach einem "next" / "get next" (ohne "edit") waere der Satz
ja zunaechst "provisorisch" eingelesen und ein nachfolgendes
"get edit" wuerde ihn /noch einmal/ einlesen.
> Ich verstehe hier aber den zweiten Teil nicht: "bereits vorher im
> Arbeitsspeicher unternommene Änderungen" haben keine Relevanz, wenn
> ich "get" oder "get edit" gebe! Der Satz steht dann in der Form
> bereit, wie er in der Datenbank steht, sonst nichts. Was vorher mit
> "insert" gemacht wurde, ist alles weg. Wo kämen wir sonst hin.
Fein!
>> eigentlich genauso typisch ist aber, dass ich den geholten Satz
>> zunaechst einmal teste und daraufhin erst entscheide, ob ich ihn
>> anfassen moechte: Je nach Anteil der zu verwerfenden Saetze kann
>> das doppelte Einlesen dann sogar effizienter sein, weil viel
>> seltener tatsaechlich ein Satz gesperrt werden muss.
>>
> Ja. Und was hieße das konkret für die FLEX-Syntax und -Semantik?
Der "Normalzustand" waere, dass Ergebnismengen (find, family, ...)
aus existierenden internen Datensatznummern bestehen (Verhalten bei
"ungenutzten" Satznummern derzeit noch etwas unklar). Beim Zugriff
auf einen Datensatz (implizit bzw. "f1nd", "get", ...) wird
dieser Datensatz in einem konsistenten Zustand (Locking auf
Betriebssystemebene evtl. notwendig) eingelesen. Dabei wird eine
Sicherheitskopie parallel zum eigentlichen Arbeitstext angelegt bzw.
eine Checksum berechnet bzw. was die "sorry-jemand-anderes-war-schneller"-
Heuristik derzeit so braucht. Ein eventuell
nachfolgendes "put" dieses Satzes unternimmt nun folgendes:
1. Satztabelle sperren (Unterlogik mit Abbruch, wenn das zu lange
dauert, der Job entscheidet dann, wie es weiter geht)
2. Pruefen, ob ein Lock auf den Datensatz besteht
falls ja: => Satztabelle freigeben, etwas warten (100ms?), zurueck
zu 1. Nach einigen Wiederholungen Ausgabe einer diagnostischen
Meldung und Abbruch (der Flex/Job muss dann entscheiden,
ob er einen Neuversuch startet, den Satz ueberspringt oder
die gesamte Verarbeitung abbricht)
3. Heuristik zur Datensatzveraenderungsbemerkung ausfuehren
falls Abweichung: => Nicht speichern, Meldung ausgeben,
Satztabelle freigeben. Flex und Job entscheiden dann wie
bei 2. ueber das weitere Vorgehen
4. Onlinesatz komplett einlesen (falls nicht bei 3. bereits
passiert)
5. Altschluessel berechnen
6. Das Wechselspiel aus PV-Routinen und Neuschluesselberechnung
fuer den Satz im Arbeitsspeicher durchfuehren
7. Logdatei aktualisieren, Satz speichern, Index unter
Beruecksichtigung der Altschluessel aktualisieren
8. .TBL freigeben
Der Normalzustand kommt also analog zu a99-Bearbeitungen ohne
Sperre von Datensaetzen aus, reagiert aber auf (fremd-) gesperrte.
"get edit" tut nun folgendes
1. Habe *ich* diesen Satz bereits gesperrt => Fertig
[oder auch nicht: Evtl. interessiere ich mich dafuer,
ob jemand anderes meine Sperre durchbrochen hat]
2. Satztabelle sperren (wie oben bei 1.)
3. Pruefe, ob (fremdes) Lock auf den Datensatz besteht
(wie oben bei 2.)
4. Sperre setzen, ***intern vermerken, dass es ein
selbstgesperrter Satz ist***
5. Onlinesatz einlesen
6. Satztabelle freigeben
[5. vor 6. hat den Vorteil, dass auch ohne zusaetzliche
Betriebssystemmechanismen die Konsistenz des eingelesenen
Satzes gewaehrleistet ist. 5. nach 6. benoetigt die etwas
aufwendigere Standard-Lesemethode des normalen "get"]
Falls der aktuelle Flex/Job der Ansicht ist, dass es sich
um einen selbstgesperrten Datensatz handelt, ist der
Ablauf von "put" der folgende:
1. Satztabelle sperren (Unterlogik mit Abbruch, wenn das zu lange
dauert, der Job entscheidet dann, wie es weiter geht)
2'. Pruefen, ob ein Lock auf den Datensatz besteht
falls nein => irgendetwas laeuft gewaltig schief, alles
beenden!
[optional, "Debug"-Modus]
3'. Heuristik zur Datensatzveraenderungsbemerkung ausfuehren
falls Abweichung: => irgendetwas laeuft gewaltig schief, alles
beenden!
]
4. Onlinesatz komplett einlesen (oder Rueckgriff auf eine von
"get edit" angelegte Zusatzkopie, aber eigentlich gibt es
dafuer keinen Bedarf: Der Ablauf hat uns /garantiert/, dass
die Online-Version exakt diejenige ist, auf der unsere
Aenderungen aufgesetzt haben)
5. Altschluessel berechnen
6. Das Wechselspiel aus PV-Routinen und Neuschluesselberechnung
fuer den Satz im Arbeitsspeicher durchfuehren
7. Logdatei aktualisieren, Satz speichern (ohne Datensatzsperre),
Index unter Beruecksichtigung der Altschluessel aktualisieren,
internen Sperr-Merker aufheben.
8. .TBL freigeben
D.h. der Ablauf ist i.W. derselbe wie beim normalen "put", es werden
nur aus den Tests 2. und 3. stellenweise andere Konsequenzen gezogen.
Das optionale "put lock" wuerde in beiden Situationen Schritt
7 modifizieren, der Satz wird dann mit gesetzter Sperre
weggeschrieben und intern vermerkt, dass der Satz gesperrt
ist/bleibt.
Einen analogen Mechanismus des internen Merkens koennte man auch
fuer die .TBL-Sperre implementieren, damit koennte ein Job die
Datenbank sperren und dennoch (quasi mit exklusivem Zugriff)
alle moeglichen Schreiboperationen durchfuehren.
Auch denkbar ist eine Variante, die das Setzen und Aufheben
von Datensatz-Sperren /ohne/ den Schutz durch die .TBL-Sperre
realisiert. Das wuerde groessere Parallelitaet erlauben, erfordert
aber eine durchaus komplexe Logik, bzw. die Abkehr vom Prinzip,
die Datensatzsperre physisch direkt beim Datensatz in der .cLD-
Datei zu vermerken. Da Datensatzsperren aber (zumindst in einer
Umgebung ohne PRESTO-Bearbeitungen) etwas eher seltenes sind,
halte ich den Aufwand hierfuer fuer eher uebertrieben.
viele Gruesse
Thomas Berger
Mehr Informationen über die Mailingliste Allegro