CRecordset - Wie Ergebnis aktualisieren ?



  • Hallo Leute!

    Ich habe hier ein CRecordset-Objekt das mit einer Interbase DB verbunden ist. Ich schicke eine Abfrage (select * from tabelle order by irgendwas) ab die sehr viele Zeilen liefert ( ~ 100.000 ).
    Das Problem ist jetzt folgendes: Wenn ich einen Satz aus diesem Ergebnis bearbeiten will, der aber zwischenzeitlich schon von einem anderen User bearbeitet wurde, gibts einen "Concurrency-Error". Mein Datensatz ist also nicht up-to-date in dem Augenblick wo ich ihn bearbeiten will. Wie kann ich entweder den Satz auf dem ich stehe aktualisieren, oder das gesamte Ergebnis ohne meine Position im Recordset zu verlieren ? 😕 (Wenn ich Requery() aufrufe stehe ich wieder am Anfang der Ergebnisses und muss dann umständlich bis zur Position vor Requery zurückfinden).
    Ich habe dann folgendes versucht: Ich mach mir ein zweites CRecordset-Objekt das genau den Satz abfragt auf dem ich stehe (select * from tabelle where primärkey = x). Dummerweise bekommt dieses Recordset Objekt nicht mit, wenn ein anderer User etwas geändert hat. User B kann zwischenzeitlich sogar den Satz löschen. Wenn ich den Satz dann neu selektiere gibts ihn angeblich noch 😕 Woran liegt das ? Wie kann man das verhindern ?



  • CRecordset::dynaset => Eine Gruppe von Datensätzen, die sich durch Aufruf der Funktion Fetch aktualisieren lassen, so daß Änderungen, die durch andere Benutzer am Recordset vorgenommen wurden sichbar werden.

    Wie wäre des damit???



  • Ja Dynasets wären echt super. Dummerweise unterstützt Interbase keine Dynasets 😞 Genaugenommen kenn ich gerade mal eine handvoll Datenbanken die das können und noch weniger ODBC Treiber die es dann unterstützen 😞
    Kennst du noch eine andere Möglichkeit ?



  • Optimistischer und pessimistischer Ansatz bzw. optimistisches und pessimistisches Sperren von Datensätzen fällt mir da als Stichwort ein. Dazu sollte eigentlich was zu finden sein. Keine Ahnung, ob es auch noch besser geht...



  • Das betrifft die Sperrlogik - Der unterschied zwischen optimistic und pessimistic locking ist AFAIK nur der Zeitpunkt zu dem der Datensatz gesperrt ist.
    Ich habe mittlerweile einen Ansatz für mein Problem gefunden. Ich bastel mir meine eigene Dynaset-Logik 😃 Ist momentan noch etwas träge bei grossen Datenmengen aber es funktioniert. Im Prinzip mach ich das so: Ich nehme das Statement auseinander und selektiere mir zunächst nur die Primary-Key Werte und pack diese für jeden Ergebnissatz (Könnte ein Speicherfresser werden - da muss ich mir noch was einfallen lassen) in eine kompackte Speicherstruktur. Dann schliess ich das Rowset wieder und positionier nur noch über mein PK-Map. Wenn ich mich dann durch mein Ergebnis-Konstrukt bewege hole ich jeweils das Ergebnis der Abfrage für genau den entsprechenden Primary-Key mit der Bedingung der Ur-Abfrage und öffne diese in einem neuen Recordset. Durch dieses ständige neu-selektieren wird die Navigation natürlich verlangsamt, dafür werden Änderungen durch Update und Delete sofort sichtbar (Für Neu hinzugefügte Sätze muss die komplette Abfrage neu abgeschickt werden).
    Vorteil:
    - Recordset ist absolut frisch und einzelne Sätze können zu jedem Zeitpunkt aktualisiert werden.
    - Suchen von Werten innerhalb der Ergebnismenge kann durch ein Paar Tricks und kluge Datenorganisation extrem vereinfacht werden.
    - MoveFirst / MoveLast dauert nicht länger als MoveNext
    - Grösse des Rowsets ist bekannt (Was bei "nicht-bulk row fetched" recordsets sonst nicht möglich ist)

    Nachteil:
    - Ausführen der Abfrage dauert länger (ca 5 Sek für 100.000 Datensätze)
    - Frisst Speicher weil der PK jedes Records in den Speicher muss
    - Für Views und andere "Non-Updateable" Ergebnisse muss parallel die klassische Version implementiert bleiben (weil diese Recordsets natürlich keinen Primary Key haben bzw nicht änderbar sind).


Anmelden zum Antworten