![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: DataSnap
DataSnap mit mehreren Datenbanken
Hallo Zusammen,
die Frage vorab: Muss die ServerMethods Klasse auch die FDConnection und alle Query beinhaltet da sie ja je nach LifeCycle für jeden angemeldeten User registriert und instanziiert wird? Mein DataSnap Server (Delphi XE7) ist verbunden mit drei Firebird 2.5 Datenbanken über FireDac. Der Server wird maximal bis zu 50 User gleichzeitig bedienen. Die meiste Zeit wird er jedoch auf Clients warten und sich langweilen. Die FDConnection und dessen Querys habe ich pro Datenbank separat in je ein DataModul gepackt. Zusätzlich gibt es für jede Datenbank ein eigenes ServerMethods DataModul. Dieses beinhaltet nur die Methoden die für die Clients gedacht sind, also ohne die Datenbankkomponenten! Ich habe es probiert und es funktioniert alles einwandfrei. Sicher bin ich mir jedoch nicht ob es nur ein Zufall ist dass kein Problem entstanden sind. Ich habe ein weiteres DataSnap Projekt welches in dem ServerMethods DataModul auch die FDConnection und alle Query beinhaltet. Das funktioniert auch einwandfrei. Gruß Kostas |
AW: DataSnap mit mehreren Datenbanken
Da der DataSnap-Server für mehrere Clients auch mehrere Threads aufmachen kann, muss man bei den Connections schon etwas aufpassen. Am einfachsten lässt sich das realisieren, wenn die Connection im ServerMethods-Datenmodul steckt, aber das ist auch nicht sonderlich performant und verbraucht auch reichlich Connections. Alternativ kann man die Connections auch thread-bezogen poolen.
Edit: Vielleicht mal hier ein bisschen nachlesen: ![]() |
AW: DataSnap mit mehreren Datenbanken
Nein, in den ServerMethods steckt ja erstmal nur der Zugriffscode für die Clientenanfragen-
Von wo letztendlich die ausgelieferten Daten kommen, ist dabei erstmal egal. Du mußt nur eventuell auf das Threading achen, also daß alles Threadsave ist, Ich hatte damals den autogenerierten Servercode genommen, das selber in eigene Klassenstrukturen umkopiert und bissl angepasst. (genauso clientseitig) z.B. Streams übertragen ist im DataSnap etwas heikel. (vorallem mit über 64 Kilobytechen) * Es gibt im Server nur eine Instanz für alle (lifecycle = server) * Bei Abfragen der Clienten wird das gewünschte DataSet aus einer globalen Liste gezogen, kurz gesperrt (Critical Section) kopiert und anschließend in Ruhe zum Clienten übertragen * Dabei werden auch paar Problemfälle behandelt, wie z.B. daß es bei TEXT knallt (beim Kopieren wird einfach ein größeres VARCHAR daraus gemacht) * bzw. seit heute wird in der Kopie auch noch eine Spalte clientspezifich angepasst (Werte geändert, bzw. eigentlich eine Art clientabhängiges CalcField angehängt) Der Server wird als DB-Cache benutzt, für längere SQL, die häufig von Vielen abgerufen werden und praktisch fast überall das Selbe enthalten (bis auf ein paar Felder für die clientseitige Gridfilterung "ist meine", was bissl schwer zu lösen ging, da man GridFilter nicht speichern und vorallem synchronisieren kann, wenn darin "Zuständiger = HierMeinName" geprüft werden soll) Und dann macht der DataSnap-Server noch paar weitere Dinge, wie ein eigener WebServer für die Hilfedateien (die Sicherheitsrichtlinien vom MS im Intranet sind echt besch***), Dateiserver für's DMS, EDI-Exporte, Backups usw. Zitat:
|
AW: DataSnap mit mehreren Datenbanken
Zitat:
Gemein ist nur, daß das in den simplen Beispielen und Versuchen (mit einem Client oder mehreren nacheinander) immer gut funktioniert. |
AW: DataSnap mit mehreren Datenbanken
Jupp, daher machen wir das übertragen der DataSets halt "manuell".
CriticalSections und Dergleichen bekommt man nicht in den Code, da die Daten erst nach Ende der Servermethoden übertragen werden und bei DataSets auch noch stückchenweise. (nur so viel, wie der Client grade braucht) Daher erstellen wir und ein ClientDataSet/MemDataset, nutzen den DataSnapReader zum Kopieren der FeldStruktur und der Inhalte, dann wird das DataSet übertragen und dem DataSnap wird mitgeteilt, daß es Owner über die Kopie ist ... wird dann von dem freigegeben, wenn fertig. So können wir die Zugriffe problemlos selber synchronisieren. Aber wem das zuviel ist, der legt die DataSets/Queries auf die DataSnapModule, lässt für jeden Clienten eine eigene Instanz erstellen. Die Connection kommt da auch mit drauf, wenn sie kein Multithread (Connectionpooling) kann ... dann ist jeder Thread alleine für sich und es gibt auch keine Probleme mehr (außer vielleicht beim RAM) DataSnap ist (zumindestens im XE) erstaunlich resourcenhungrig, so daß schnell der RAM voll ist, vorallem in einem 32-Bit-Programm. :stupid: |
AW: DataSnap mit mehreren Datenbanken
Zitat:
|
AW: DataSnap mit mehreren Datenbanken
Vielen vielen Dank für die ausführlichen Infos.
habe ich das jetzt wirklich richtig verstanden, wenn der DataSnap Server als 32Bit kompiliert wird, benötigt DataSnap mehr Speicher als wenn er als 64Bit kompiliert werden würde? Wenn ja, wie hängt das zusammen? Zum eigentlichen Problem, wenn bei 150 User "nur" 15-20GB RAM verbraten werden, würde mich das noch nicht aus der Ruhe bringen. Den RAM kann ich wirklich ignorieren. Mein DataSnap Server wird jetzt nicht so umfangreich aber ein paar Dutzend Querys werden das schon. Ich wollte einfach nur die Querys thematisch auf mehrere DataModule verteilen wegen der Wartbarkeit. Bei Anwendungen mit ein paar hundert Querys alles auf das ServerMethods Datamodul zu packen ist zwar möglich aber eben danach nur sehr schwer wartbar. In diesem Projekt mit den drei Datenbanken habe ich eh drei TDSServerClass die auch drei ServerMethod Klassen registriert, und wie ich das Verstanden habe bei LifeCycle=Session werden alle drei ServerMethod Module instanziiert pro Session. Der Zugriff von den Public ServerMethods auf die Querys währe damit sichergestellt. Wäre es denkbar dass man nur wegen der Wartbarkeit weitere ServerMethods DataModule anlegen und die Querys sachlich trennt, sie würde ja alle mit instanziiert pro Session? Eigentlich wollte ich in den ServerMethods ausschließlich Methoden für die Clients bereitstellen. Die sonstige Logik sollte eben auch mehrere weitere DataModuls aufgeteilt werden. Aktuell funktioniert es so aber ihr meint, es wird Probleme geben. Wie könnte ich bitte vom ServerMethods ThreadSave auf meine Methode im DataModul zugreifen, etwa so? Das wäre zu einfach :-)
Delphi-Quellcode:
function TdmServerMethodsZMI.ZMI_GetBauDataSetThreadSave(BauNr: integer): TDataSet; var LDataSet: TDataSet; begin TThread.Synchronize(nil, procedure begin LDataSet := dmDALZMI.GetBauDataSet(BauNr); end); Result := LDataSet; end; Aktuell habe ich in ein DataModul das:
Delphi-Quellcode:
Im ServerMethods DataModul das:
function TdmDALZMI.GetBauDataSet(BauNr:integer): TDataSet;
begin qrGetBau.Active := False; qrGetBau.Params[0].Value := BauNr; qrGetBau.Active := True; result := qrGetBau; end;
Delphi-Quellcode:
function TdmServerMethodsZMI.ZMI_GetBauDataSet(BauNr: integer): TDataSet;
begin result := dmDALZMI.GetBauDataSet(BauNr); end; Gruß Kostas |
AW: DataSnap mit mehreren Datenbanken
Zitat:
|
AW: DataSnap mit mehreren Datenbanken
Jupp, mit 32 Bit ist nach 2 GB Schluß (3,8 GB mit entsprechenden Hacks und wenn alles dafür kompatibel ist)
Zitat:
Drum auch meine Lösung mit dem umkopieren. Das kopierte DataSet wird dann nur für diesen einen Aufruf verwendet und ist somit threadsave (wenn die verwendete TDataSet-Implementation nicht dennoch irgendwelche threadunsicheren globalen Dinge veranstaltet) Grundsätzlich sicher ist nur, wenn sich DS ums Freigeben kümmert, wenn es nichts Globales im Apps gibt (jede Connection bekommt was Eigenes), bzw. wenn man alles Globales selber "vollständig" absichern kann, und wenn die DataSets auch nicht global sind, sondern werden immer neu erstellt, für die jeweilige Anfrage. |
AW: DataSnap mit mehreren Datenbanken
Zitat:
![]() Wenn du ein TDSServerModule verwendest und mit TDataSetProvider-Instanzen arbeitest, kannst du die jeweiligen DataSetProvider auf den zusätzlichen Datenmodulen über RegisterProvider dem TDSServerModule bekannt machen. Dann sind die im Client hinterher auch wiederzufinden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:03 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