Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Thread getriebene SQLite Zwischenschicht?! (https://www.delphipraxis.net/182606-thread-getriebene-sqlite-zwischenschicht.html)

Mavarik 4. Nov 2014 16:50

Thread getriebene SQLite Zwischenschicht?!
 
Hallo Zusammen!

Ich habe folgende Situation:

Eine Software die in verschiedenen Filialen eingesetzt wird.
Zur Zeit hat jede Filiale einen eigenen MySQL-Server und es gibt einen globalen MySQL-Server im Internet.
Direkt auf dem globalen Server zu arbeiten ist zu langsam, da teilweise die Internetverbindung zu schlecht, langsam und instabil ist.

Es gibt zwei "FEDERATED" Tabellen. Eine für die Log's die andere für die Datenbank-Versionsverwaltung.

Wenn eine Datenbank geöffnet wird, schaut die Software erst nach, ob auf dem Server Datensatzänderungen sind, die erst auf den lokalen Server übertragen werden müssen. Nach dem Close schreibt die Software die geänderten Datensätze auf den globalen Server und gibt die Datenbank wieder frei.

Soweit so "gut"... Das funktioniert so recht gut seit ca. 3 Jahren.

Leider:
a.) passiert es immer wieder, dass während dem Datentransfer die Verbindung zum Server abraucht.
b.) ist ggf. die Wartezeit nach einem Open der Datenbank recht lange, wenn die andere Seite viele Daten eingefügt hat.

Daher überlege ich eine Zwischenschicht auf beiden Seiten ein zu führen. Diese soll als eigenständige Software oder als Thread im Hintergrund für den Abgleich sorgen.

Als Idee hatte ich eine Firedac Memtable gedacht, diese soll sowohl als Cache als auch als Puffer für die Übertragung dienen.

Oder hat jemand eine bessere Idee. (Bitte nur, wenn ich nicht das komplette Konzept umstellen muss) :stupid:

Grüsse Mavarik

Jumpy 4. Nov 2014 17:12

AW: Thread getriebene SQLite Zwischenschicht?!
 
Ich hab jetzt keine Ahnung von MySQL, aber kann man das die Datenbank(server) nicht selber (mit entsprechenden Tools) erledigen lassen? Stichworte vllt. Replikation oder Spiegelung von Datanbanken?

rapante 4. Nov 2014 17:14

AW: Thread getriebene SQLite Zwischenschicht?!
 
Was spricht denn gegen eine Master/Slave-Replikation?
Wir haben das bei uns zumindest so implemntiert, dass jede Filiale einen eigenen Slave-Server für Lesezugriffe hat
und geschrieben wird auf dem entfernten Master.

p80286 4. Nov 2014 18:16

AW: Thread getriebene SQLite Zwischenschicht?!
 
Schau mal hier rein, ich denke, daß sollte Dir weiter helfen.

Gruß
K-H

Mavarik 4. Nov 2014 18:24

AW: Thread getriebene SQLite Zwischenschicht?!
 
Das hat sich eigentlich von Anfang an ausgeschlossen, da SlaveA nicht die Datenbank auf SlaveB sperren kann.

Daher funktioniert das nicht..

Mavarik

PS.: Die Frage lautet... Firemonkey MemTable oder "nimm besser einen balSchnickschnackProviderComanndqueryproducer" <- keinen Plan...

Dachte sowas mit ApplyUpdates (noch nie versucht Schnickschnack...)

Sir Rufo 4. Nov 2014 19:51

AW: Thread getriebene SQLite Zwischenschicht?!
 
Das mit dem Thread verstehe ich nicht. Was ich verstehen würde wäre eine Service-Anwendung, die für den Abgleich sorgt. Allerdings sehe ich die nicht auf der Seite vom Hauptserver, der braucht die nicht.

Der Service kümmert sich fortlaufend um den Abgleich mit dem Hauptserver. Dazu sperrt er die Datenbank (so wie die Anwendung z.B. Status 1), trägt die Daten vom Hauptserver ein und gibt die Datenbank wieder frei (Status 0).

Während die Anwendung läuft erfolgt kein Abgleich. Wird die Anwendung beendet, dann wird die nicht freigegeben, sondern in den Status 2 (neue lokale Daten vorhanden) und ist damit für die Anwendung weiterhin gesperrt.

Jetzt verbindet sich der Service wieder mit der Datenbank, setzt den Status auf 1, überträgt die Daten zum Hauptserver und macht ansonsten den normalen Abgleich vom Hauptserver.

Dejan Vu 4. Nov 2014 20:26

AW: Thread getriebene SQLite Zwischenschicht?!
 
Die Idee von Sir Rufo würde bedeuten, irgendwie irgendwo ein zweites Programm zu starten. Fände ich auch naheliegend, wobei dann eventuell noch kleinere Synchronisationsprobleme gelöst werden müssen (Datensatz wird aktualisiert, während er in Bearbeitung ist).

Die Idee mit dem Thread ist dann verständlich, wenn kein zweites Programm laufen soll. Dann ist dieser 'Service' eben ein Thread.

Sir Rufo 4. Nov 2014 21:06

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von Dejan Vu (Beitrag 1278691)
Die Idee von Sir Rufo würde bedeuten, irgendwie irgendwo ein zweites Programm zu starten. Fände ich auch naheliegend, wobei dann eventuell noch kleinere Synchronisationsprobleme gelöst werden müssen (Datensatz wird aktualisiert, während er in Bearbeitung ist).

Die Idee mit dem Thread ist dann verständlich, wenn kein zweites Programm laufen soll. Dann ist dieser 'Service' eben ein Thread.

Das Sync-Problem ist doch schon gelöst (so wie es jetzt auch schon ist):

AKTUELL:
  • Anwendung startet
    • Warten auf freie Datenbank (0)
    • Datenbank sperren (1)
    • Daten vom Hauptserver
  • Anwendung endet
    • Daten zum Hauptserver
    • Datenbank freigeben (0)
VORSCHLAG:
  • Anwendung startet
    • Warten auf freie Datenbank (0)
    • Datenbank sperren (1)
  • Anwendung endet
    • Datenbank freigeben (2)
  • Service Abgleich
    • Warten auf freie Datenbank (2)
    • Datenbank sperren (1)
    • Daten zum Hauptserver
    • Daten vom Hauptserver
    • Datenbank freigeben (0)
  • Service Abgleich
    • Warten auf freie Datenbank (0)
    • Datenbank sperren (1)
    • Daten vom Hauptserver
    • Datenbank freigeben (0)
Alles was es da an Sync-Problemen aktuell gibt, werden mit diesem Ansatz nicht gelöst, ist aber auch nicht Gegenstand der Frage gewesen ;)

p80286 5. Nov 2014 10:52

AW: Thread getriebene SQLite Zwischenschicht?!
 
Was ich nicht verstehe "Datenbank sperren" ist doch ein unnötiger Flaschenhals Datensatz/sätze wäre mir einleuchtender.

Gruß
K-H

Dejan Vu 5. Nov 2014 11:10

AW: Thread getriebene SQLite Zwischenschicht?!
 
Genau, denn damit wird die lange Wartezeit bei vielen Änderungen nicht vermieden. Und wenn man den Datensatz sperrt, dann so kurz wie möglich und dann gibt es wieder 'race conditions', die gelöst werden müssen. Aber das ist ja alles keine Hexerei. Wenn z.B. ein Datensatz gerade zum Ändern gesperrt ist, kann er nicht aktualisiert werden. Dann würde eine Aktualisierung u.U. einen Reconcilekonflikt auflösen (Feld A wurde lokal und global verändert, wer gewinnt?)

Mavarik 5. Nov 2014 12:21

AW: Thread getriebene SQLite Zwischenschicht?!
 
@Dejan Vu & @Sir Rufo

Ich macht Euch viel zu viele Gedanken. Das Funktioniert doch schon alles...

OnBeforeOpen
- Get New & Lock
OnAfterClose
- Post New & Unlock

Leider habe ich auf ein eindeutiges ID (Autoinc) bei Design gesetzt... War ein Fehler! Aber darum geht es ja gar nicht.

Nur als kleinen Hintergrund:
Das Ganze ist aus der ENZ-BTreeIsam aus DOS-Zeiten noch. (Ja ich bin alt...) Und da wurde halt eine SeekNr genommen.
Dann habe ich die Routinen für Windows 95 und Delphi 3 auf Windows umgestellt.
Mit Delphi 4 (glaube ich) habe ich eigene Datenbank Komponenten geschrieben die auf diese Datenbank aufsetzen.
Mit Delphi 7 habe ich das ganze (ohne eine Zeile am Hauptprogramm zu ändern) auf MySQL umgestellt)! Und aus der SeekNr wurde das ID.
Mit Delphi 2007 dann den Serverübergreifenden Sync (auch wieder ohne eine Zeile am Hauptprogramm zu ändern)!
Jetzt stehen halt mal wieder Verbesserungen an und ein Wechsel zu FireDac um die Fehler der alten MySQL Komponenten los zu werden.

Da ich FireDac entwas "unübersichtlich" finden... Meine Frage ob ich mit ner MemTable die im Hintergrund auf den Server das Update durchführt, auf dem richtigen Weg bin oder lieber etwas anderes nehmen soll.

An eine Service-Anwendung hatte ich auch schon gedacht... Läßt sich nur immer so schlecht debuggen.

Vielleicht auch lieber einfach per TCP/IP in eine App auf dem lokalen Server einloggen die Daten "nativ" also binär übertragen und auf dem lokalen Server erst in SQL umwandeln. ALLE Daten liegen sowieso in Records vor. Eine TCP/IP Übertragung der nativen Daten, wäre warscheinlich sowieso um den Faktor 10x bis 100x schneller... Und dann kann die "Serverapp" losorgeln.

Oder und daher der Title "Thread" die Umwandlung lokal innerhalb der Software und dann auf den Server. Die Software läuft sowieso fast 24/7.

Grüsse Mavarik

mm1256 5. Nov 2014 14:58

AW: Thread getriebene SQLite Zwischenschicht?!
 
[OffTopic]

Zitat:

Zitat von Mavarik (Beitrag 1278751)
Das Ganze ist aus der ENZ-BTreeIsam aus DOS-Zeiten noch. (Ja ich bin alt...) . . .

Nicht nur du :) aber, Mann o Mann, das war noch ne Datenbank.

[/OffTopic]

Zum Thema bzw. zur Frage: MemTable würde ich persönlich nicht bevorzugen, es sei denn, du kannst das in Transaktionen verpacken. Da wäre die TCP/IP-Variante schneller, und wahrscheinlich auch sicherer, weil transaktionsfähig 8-)

Gruss vom MM Baujahr 56

Mavarik 5. Nov 2014 16:04

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von mm1256 (Beitrag 1278779)
Nicht nur du :) aber, Mann o Mann, das war noch ne Datenbank.

Funktionierte, kaum erkennbare Fehler... schnell... jojojo
Zitat:

Zitat von mm1256 (Beitrag 1278779)
Zum Thema bzw. zur Frage: MemTable würde ich persönlich nicht bevorzugen, es sei denn, du kannst das in Transaktionen verpacken. Da wäre die TCP/IP-Variante schneller, und wahrscheinlich auch sicherer, weil transaktionsfähig 8-)

Wieso transaktionsfähig?

Dejan Vu 5. Nov 2014 16:20

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von Mavarik (Beitrag 1278676)
...
Leider:
a.) passiert es immer wieder, dass während dem Datentransfer die Verbindung zum Server abraucht.
b.) ist ggf. die Wartezeit nach einem Open der Datenbank recht lange, wenn die andere Seite viele Daten eingefügt hat.
...

Zitat:

Zitat von Mavarik (Beitrag 1278751)
@Dejan Vu & @Sir Rufo
Ihr macht Euch viel zu viele Gedanken. Das Funktioniert doch schon alles...

OnBeforeOpen
- Get New & Lock
OnAfterClose
- Post New & Unlock

Also wenn alles funktioniert, was willst Du dann? Ich denke, es geht gerade so *nicht*. Da kann man dann schon mal nachdenken. Aber da alles funktioniert, ist ja auch alles klar und es gibt keine Probleme.

Mavarik 5. Nov 2014 16:31

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von Dejan Vu (Beitrag 1278789)
Also wenn alles funktioniert, was willst Du dann? Ich denke, es geht gerade so *nicht*. Da kann man dann schon mal nachdenken. Aber da alles funktioniert, ist ja auch alles klar und es gibt keine Probleme.

- wie gesagt. Es gibt Abbrüche und ich will die MySQL Componenten wechseln.
- und modernisieren.

Nur weil etwas funktioniert bedeutet es doch nicht, dass es nicht noch besser funktionieren kann...
Aber meine Frage war ja Firedac Memtable ja oder etwas anderes.

p80286 5. Nov 2014 16:44

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von Dejan Vu (Beitrag 1278789)
Also wenn alles funktioniert, was willst Du dann? Ich denke, es geht gerade so *nicht*. Da kann man dann schon mal nachdenken. Aber da alles funktioniert, ist ja auch alles klar und es gibt keine Probleme.

Mann, es läuft nicht optimal und er wehrt sich alles auf den Müll zu schmeißen, nur um die Superduperdistributetobjectorienteddatastoragelösu ng zu installieren, bei der in 3 Jahren jeder die Schulter zuckt und fragt was das alte Zeug soll.

Gruß
K-H

Mavarik 5. Nov 2014 17:19

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von p80286 (Beitrag 1278800)
...und er wehrt sich alles auf den Müll zu schmeißen...

Genau... 1 Mio. Zeilen Source die fest mit der ENZ ISAM verknüpft sind, baut man nicht mal eben um auf Firedac...

Besonders nicht, wenn man dafür nicht bezahlt wird...

Mavarik :stupid:

mm1256 5. Nov 2014 19:32

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von Mavarik (Beitrag 1278784)
Wieso transaktionsfähig?

na ja, was passiert denn wenn während eines Schreibvorganges ein Problem auftritt (PC bzw. OS bleibt hängen, Stromausfall...). Dann hängt die MemTable "irgendwo"....und du hast ein Problem.

Zitat:

Zitat von Mavarik
Besonders nicht, wenn man dafür nicht bezahlt wird...

Macht es dann überhaupt Sinn sich über zeitaufwändige Optimierungen Gedanken zu machen?

Dejan Vu 6. Nov 2014 08:44

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von p80286 (Beitrag 1278800)
Mann, es läuft nicht optimal und er wehrt sich alles auf den Müll zu schmeißen, nur um die Superduperdistributetobjectorienteddatastoragelösu ng zu installieren, bei der in 3 Jahren jeder die Schulter zuckt und fragt was das alte Zeug soll.

Wo steht denn, 'alles auf den Müll zu schmeißen' sei eine Lösung?
Wenn man die Wartezeiten während des Abgleiches nicht will, dann kann/muss man das im Hintergrund machen. Und wenn man das im Hintergrund macht, muss man eben noch 1-2 Dinge beachten. Hört sich jetzt nicht nach einer Lösung an, bei der man alles auf den Müll schmeißen muss. Und eine "objektkorientierte Datastoragelösung" muss das auch nicht werden, weil man das auch in VB oder C programmieren kann. :stupid:

Zitat:

Zitat von Mavarik (Beitrag 1278794)
- wie gesagt. Es gibt Abbrüche und ich will die MySQL Componenten wechseln.
- und modernisieren.
...

Und die Wartezeiten bei vielen Änderungen vermeiden?

Wenn die Datenbankzugriffe nicht gekapselt sind, wird das allerdings eine größere Operation.

Du wirst schon eine pragmatische Lösung finden. Ich würde -wenn überhaupt- zuerst die DB-Komponenten austauschen und dabei kapseln. Wenn alle DB-Zugriffe abstrahiert sind (d.h. in Klassen gekapselt) kann man die Reconcile-Logik einbauen, d.h.: Daten werden lokal und global verändert, wer gewinnt? Muss man aber nicht.

Mavarik 6. Nov 2014 10:35

AW: Thread getriebene SQLite Zwischenschicht?!
 
Zitat:

Zitat von mm1256 (Beitrag 1278827)
Macht es dann überhaupt Sinn sich über zeitaufwändige Optimierungen Gedanken zu machen?

Ja, denn die Software nutze ich "selber".


Zitat:

Zitat von Dejan Vu (Beitrag 1278867)
Wenn die Datenbankzugriffe nicht gekapselt sind, wird das allerdings eine größere Operation.

So gesehen sind die "eigentlich" zu 100% gekapselt.
Beispiel:

Meine TISAMEdit Komponente hat eine Verknüpfung zu einer TISAMBase Komponente und kann den da gespeicherten Record lesen und schreiben...

Die Verarbeitung ist ganz normal ENZ :stupid:

Delphi-Quellcode:
Adressen : TISAMBase;

begin
  Adressen.BTInitIsam;
  Adressen.Open := true;
  RetKey := Adressen.Findkey(KeyNr,SeekNr,SearchKey);
  if (RetKey = SearchKey) and (Adresse.ISAMError = ISAMOK) then
    begin
      Adressen.GetRec(SeekNr);
      Adressen.Edit;
      ...
      Adressen.PutRec(SeekNr);
      Adressen.AddKeys;
    end;
   Adressen.Open := false;
   Adressen.BTDeInitIsam;
end;
Naja und die Findkey, GetRec, Edit, Put, AddKeys usw. werden halt in der ehemaligen ISAM umgesetzt in SQL.

Mavarik

PS.: Aber die eigentlich Frage war immer noch nach der Richtigen FireDac Komponente für die Zwischenschicht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz