Guten Tag,
ich bin leider gerade über ein Problem bei der Konzeption eines neues Projektes gestoßenl, mit dem ich selbst nicht ganz klar komme.
Es sollte Firebird 2.1 + IBO unter Delphi7 zum Einsatz kommen.
Ich möchte einmal kurz den Ablauf schildern:
Es geht darum große Datenmengen an ~250 Clients zu schicken.
Dabei können alle paar Sekunden Änderungen in der Datenmenge auftauchen, welche Schnellstmöglichst zu den Clients muss.
Immer die komplette Datenmenge zu selektieren und an die Clients zu schicken ist weder per "Polling" und selbst mit "Events" nicht praktikabel.
Einige Testläuft zeigten das im Prinzip die Datenbank in die Knie'e geht / die Query/Übertragung selbst zu lange dauert.
Es reicht allerdings auch nur die Änderungen zu senden, welche wesentlich kleiner sind! Gut. Ausgedacht, umgesetzt und getestet.
Soweit so gut. Bis ich dann auf ein "kleines" Problem gestoßen bin, welchem ich wohl ohne Hilfe nicht gewachsen bin
Nun zum Problem:
Ich habe das ganze über einen Before-Update Trigger umgesetzt, der bei der Änderung eines Datensatzes einen Timestamp protokolliert. Die Clients wissen welchen Datenbestand ( "zeitlichen") sie lokal haben und requesten immer alle Änderungen seit der letzten Aktualisierung.
Nun wird aber der Before-Update Timestamp beim ausführen des Update-SQLs gesetzt. Zu diesem Zeitpunkt ist die Transaktion unter Umständen NICHT commited. Beim Commit wird dann der - zu diesem Zeitpunkt - "alte Timestamp" als letztes Änderungsdatum vermerkt.
Dadurch kann - je nach Zeitraum zwischen dem Update und dem Commit - eine große Zeitlücke entstehen in der die Änderung nicht erkannt wird. Dieser Fall ist fatal und nicht tragbar :-)
D.h. hier nochmal ein Ablauf-Bsp:
Zeitpunkt 1: Client holt sich alle Daten ab.
Zeitpunkt 2: Server ändert Datensatz. (noch kein Commit)
Zeitpunkt 3: Client holt sich alle Änderungen seit Zeitpunkt 1. (findet Änderung 2 noch nicht, da noch nicht commited) und glaubt er hat alle Daten bis Zeitpunkt 3.
Zeitpunkt 4: Server commited (Schreibt Zeitpunkt 2! als Änderungsdatum).
Zeitpunkt 5: Client holt sich alle Änderungen seit Zeitpunkt 3. (Ließt die Änderung nicht, da Sie mit Zeitpunkt 2 eingetragen ist)
--> Damit wurde die Änderung von Zeitpunkt 2 vom System verschluckt.
Lösungsansatz:
Ich muss den Timestamp des Commit's setzen, und nicht den Zeitpunkt der Änderung. Hier habe ich aber leider keine Ahnung wie, denn im After-Update Trigger kann ich ja keinen Wert des Datensatzes in Firebird 2.1 mehr ändern.
Den Timestamp manuell nach dem Update zu setzen ist aufgrund der massiven größe des restlichen Systems stark fragwürdig.
Bin für alle Ideen sehr dankbar :-)
Hoffe dazu fällt jemanden etwas ein, bin mittlerweile etwas ratlos :[
ich bin leider gerade über ein Problem bei der Konzeption eines neues Projektes gestoßenl, mit dem ich selbst nicht ganz klar komme.
Es sollte Firebird 2.1 + IBO unter Delphi7 zum Einsatz kommen.
Ich möchte einmal kurz den Ablauf schildern:
Es geht darum große Datenmengen an ~250 Clients zu schicken.
Dabei können alle paar Sekunden Änderungen in der Datenmenge auftauchen, welche Schnellstmöglichst zu den Clients muss.
Immer die komplette Datenmenge zu selektieren und an die Clients zu schicken ist weder per "Polling" und selbst mit "Events" nicht praktikabel.
Einige Testläuft zeigten das im Prinzip die Datenbank in die Knie'e geht / die Query/Übertragung selbst zu lange dauert.
Es reicht allerdings auch nur die Änderungen zu senden, welche wesentlich kleiner sind! Gut. Ausgedacht, umgesetzt und getestet.
Soweit so gut. Bis ich dann auf ein "kleines" Problem gestoßen bin, welchem ich wohl ohne Hilfe nicht gewachsen bin
Nun zum Problem:
Ich habe das ganze über einen Before-Update Trigger umgesetzt, der bei der Änderung eines Datensatzes einen Timestamp protokolliert. Die Clients wissen welchen Datenbestand ( "zeitlichen") sie lokal haben und requesten immer alle Änderungen seit der letzten Aktualisierung.
Nun wird aber der Before-Update Timestamp beim ausführen des Update-SQLs gesetzt. Zu diesem Zeitpunkt ist die Transaktion unter Umständen NICHT commited. Beim Commit wird dann der - zu diesem Zeitpunkt - "alte Timestamp" als letztes Änderungsdatum vermerkt.
Dadurch kann - je nach Zeitraum zwischen dem Update und dem Commit - eine große Zeitlücke entstehen in der die Änderung nicht erkannt wird. Dieser Fall ist fatal und nicht tragbar :-)
D.h. hier nochmal ein Ablauf-Bsp:
Zeitpunkt 1: Client holt sich alle Daten ab.
Zeitpunkt 2: Server ändert Datensatz. (noch kein Commit)
Zeitpunkt 3: Client holt sich alle Änderungen seit Zeitpunkt 1. (findet Änderung 2 noch nicht, da noch nicht commited) und glaubt er hat alle Daten bis Zeitpunkt 3.
Zeitpunkt 4: Server commited (Schreibt Zeitpunkt 2! als Änderungsdatum).
Zeitpunkt 5: Client holt sich alle Änderungen seit Zeitpunkt 3. (Ließt die Änderung nicht, da Sie mit Zeitpunkt 2 eingetragen ist)
--> Damit wurde die Änderung von Zeitpunkt 2 vom System verschluckt.
Lösungsansatz:
Ich muss den Timestamp des Commit's setzen, und nicht den Zeitpunkt der Änderung. Hier habe ich aber leider keine Ahnung wie, denn im After-Update Trigger kann ich ja keinen Wert des Datensatzes in Firebird 2.1 mehr ändern.
Den Timestamp manuell nach dem Update zu setzen ist aufgrund der massiven größe des restlichen Systems stark fragwürdig.
Bin für alle Ideen sehr dankbar :-)
Hoffe dazu fällt jemanden etwas ein, bin mittlerweile etwas ratlos :[
Comment