Home Forum Nuclos Entwicklung Makros und Regeln MasterDataDelegate viel zu langsam

Ansicht von 11 Beiträgen - 1 bis 11 (von insgesamt 11)
  • Autor
    Beiträge
  • #4416
    Yves Hoeppe
    Teilnehmer

    Hallo,

    mir ist aufgefallen, dass sowohl das Benutzen der Methoden

    MasterDataDelegate.getInstance().create(…)
    MasterDataDelegate.getInstance().update(…)
    MasterDataDelegate.getInstance().remove(…)

    als auch das Löschen von mehreren Datensätzen über die Clientoberfläche einer beliebigen Entität bzw. der Import von Daten über die Strukturdefinition/Objektimport extrem langsam ist. Sicher benutzen die beiden letztgenannten ebenfalls intern die MasterDataDelegate-Methoden…

    Gehe ich beispielsweise direkt in die Datenbank und lösche alle Datensätze aus einer Tabelle (ca. 10.000 Datensätze) dauert das 2sec. Am Rechner scheint es also nicht zu liegen… Lösche ich jedoch genauso viele Datensätze einer Entität über die Clientoberfläche, dauert das bis zu 10min oder gar länger. Für einige (zeitkritische) Fälle ist das inakzeptabel.

    Anzumerken ist wohl noch, dass sich Client und Server(Applikation und Datenbank) als Entwicklungssystem mit einem einzigen Benutzer auf demselben Rechner befinden und daher keine übermäßige Last oder Übertragungszeiten bestehen.

    Gibt es vielleicht bei den MasterDataDelegate-Funktionen ein Thread.sleep-Intervall, welches irgendwie per Parameter herabgesetzt werden kann?

    Ebenfalls wäre nicht schlecht, wenn es MasterDataDelegate-Methoden gäbe, die einem erlauben, mehrere MasterDataVOs auf einen Schlag an den Server zu übergeben und erzeugen, updaten bzw. löschen zu lassen… Für jeden Datensatz einen extra Server-Call zu machen ist oft schwachsinnig und unperformant…

    Irgendwie brauche ich da eine Lösung für das Problem… Vielleicht gibt es ja schon eine…

    #4422
    Thomas Schiffmann
    Teilnehmer

    Hallo hoeppi,

    die Verwendung der Delegates im Nuclos-Client ist natürlich nicht mit der direkten Ausführung von SQL-Befehlen auf der Datenbank zu vergleichen, da ja sowohl Nuclos-Client als auch Nuclos-Server einiges an Funktionalität ergänzen (sonst könnten Sie ja schließlich auch direkt mit der Datenbank arbeiten).

    Während Sie beim Absetzen eines SQL-Befehls nur den Befehl an die Datenbank schicken, und die Datenbank diesen Befehl hochperformant intern verarbeiten kann, kommen in Nuclos noch diverse weitere Aktionen hinzu. Neben den generischen Berechtigungsprüfungen und Validierungen und der Ausführung von Geschäftsregeln spielen dabei natürlich auch die technisch bedingten Rahmenbedingungen eine Rolle. Da es sich um eine Client-Server-Architektur handelt, muss eine Kommunikation zwischen Client und Server erfolgen, die eine Interprozess-Kommunikation und somit eine Serialisierung und Deserialisierung von Daten erfordert. Sobald die Daten am Server angekommen sind, muss eine Authentisierung und Autorisierung des Zugriff erfolgen, es müssen Transaktionen verwaltet werden und es müssen Transformationen für das Objekt-relationale Mapping durchgeführt werden. Je nach Konfiguration der Entität werden evtl. auch noch Logbuch-Einträge erstellt und abhängig von der ausgeführten Delegate-Methode müssen für den Aufruf auch noch Daten zurückgeliefert werden.

    Selbstverständlich haben Sie Recht, dass es schwachsinnig ist, jeden der 10.000 Datensätze einzeln zu übertragen. Die Schlußfolgerung ist aber natürlich nicht, dass die von Ihnen genannten Methoden entsprechend anzupassen sind, sondern dass diese Methoden eben nicht für diese Datenmengen geeignet sind. Sie könnten z.B. eine Server-Erweiterung implementieren, die die gesammelten Daten entgegennimmt und in die Datenbank schreibt. Dann können Sie auch die Funktionen überspringen, die für Ihren Anwendungsfall gar nicht benötigt werden. Die Konsistenz der Daten (hinsichtlich der Aspekte, die nicht von der Datenbank sichergestellt werden) müssen Sie dann aber selbst sicherstellen.

    Viele Grüße
    tsc

    #4425
    Yves Hoeppe
    Teilnehmer

    [quote=“tsc“ post=3577]
    Die Schlußfolgerung ist aber natürlich nicht, dass die von Ihnen genannten Methoden entsprechend anzupassen sind, sondern dass diese Methoden eben nicht für diese Datenmengen geeignet sind. Sie könnten z.B. eine Server-Erweiterung implementieren, die die gesammelten Daten entgegennimmt und in die Datenbank schreibt. Dann können Sie auch die Funktionen überspringen, die für Ihren Anwendungsfall gar nicht benötigt werden. Die Konsistenz der Daten (hinsichtlich der Aspekte, die nicht von der Datenbank sichergestellt werden) müssen Sie dann aber selbst sicherstellen.
    [/quote]

    Genau das ist ja der Punkt. Ich will mich ja nicht selbst um die Konsistenz der Daten kümmern. Dann bräuchte ich Nuclos nicht zu verwenden. Der Tatsache, dass zwischen Applikationsserver bzw. Client und Datenbank Zeitunterschiede entstehen, bin ich mir dabei durchaus bewusst. Ich hatte gehofft, dass es für dieses (meiner Meinung nach übliche Problem) bereits etwas gibt. Gab es denn für sowas bisher nie Bedarf? Ich verstehe das nicht… Was macht ein Kunde, wenn es bei ihm häufiger vorkommt, dass er mal 10.000 Datensätze auf einen Schlag löschen muss? Er kann ja nicht 10min warten. Muss dann jedes Mal etwas Individuelles neu programmiert werden?

    #4427
    Ramin Goettlich
    Teilnehmer

    Hallo hoeppi,

    wie oben beschrieben, hängt am Löschen eines Datensatzes in einem komplexen fachlichen System mehr als das reine Entfernen des Datensatzes aus der Datenbank – und das kostet nun mal Zeit. Beides geht nicht 😉

    Was ist denn der Hintergrund Ihrer Anforderung? Es fällt vielleicht leichter, zu helfen, wenn Sie den Fall aus fachlicher Sicht etwas erläutern. Warum löschen Sie denn regelmässig 10.000 Datensätze (ohne 10 Minuten darauf warten zu können)?

    Grüsse,
    nuclosian

    #4428
    Thomas Schiffmann
    Teilnehmer

    Hallo hoeppi,

    Gab es denn für sowas bisher nie Bedarf?

    In der Tat ist uns (bzw. zumindest mir) bisher kein konkreter Anwendungsfall bekannt, in dem dies gefordert wurde. Stammdaten können meistens nicht so ohne Weiteres gelöscht werden, da sich Bewegungsdaten fast immer darauf beziehen. Bewegungsdaten hingegen stellen meistens Geschäftsvorfälle irgendeiner Art dar und müssen daher in der Regel
    archiviert werden. Können Sie Ihren Anwendungsfall vielleicht kurz schildern? (Edit: da war einer schneller mit der Frage :))

    Natürlich ist es das Ziel von Nuclos, so viele Anwendungsfälle wie möglich abbilden zu können. Für spezielle Anwendungsfälle ist aber leider manchmal eine spezielle Implementierung notwendig.

    Viele Grüße
    tsc

    P.S. bzgl. Objektimport: haben Sie auch im Modus „Direktimport“ keine zufriedenstellenden Ergebnisse erreicht?

    #4429
    Markus Glitzner
    Teilnehmer

    Hallo!

    Auch ich hatte Anfangs das selbe Problem beim Datenimport wie hoeppie (wurde auch hier im Forum diskutiert). Da bei uns ca 100.000 Daten in kurzen Abständen von anderen System importiert bzw. Abgeglichen werden, ist die nuclos eigene Import Funktion weder funktional noch performancemäßig dafür geeignet.

    Allerdings bei solchen Imports, ist meiner Meinung nach sowieso immer eine individuelle Lösung besser und die Überprüfungen seitens nuclos unnötig bzw. sogar unerwünscht.

    Die einfachste und effektiefste Lösung war in meinem Fall eine Stored Precedure, die über eine Regel bzw. über die Jobsteuerung aufgerufen wird.

    Gruß
    Hugo

    #4431
    Yves Hoeppe
    Teilnehmer

    Vielen Dank für die vielen Antworten!!!

    Zunächst möchte ich anmerken, dass ich keinem hier was Böses will… Wahrscheinlich hätte ich für den Thementext besser „MasterDataDelegate viel zu langsam für konkreten Fall“ wählen sollen, damit sich niemand verärgert fühlt. Es war nicht mein Ansinnnen, jemandem auf den Schlips zu treten. Da mir der allgemeine Tenor dieser Diskussion das jedoch vermittelt, möchte ich mich dafür entschuldigen. Sehen Sie das bitte eher als Anregung als als Beschimpfung.

    Ich weiß, dass die Vorgänge im Hintergrund komplex sind und bin eigentlich eher davon ausgegangen, dass die Zeit an der Stelle verbraten wird, an der die Daten vom Client an den Server übertragen werden, also die Interprozess-Kommunikation, wie tsc bereits beschrieben hat.

    Dass es tatsächlich keinen Bedarf gibt, finde ich eben verwunderlich. Ich stelle mir da beispielsweise ein System vor, bei dem Artikelbestände sich regelmäßig ändern und über verschiedene Lager von Fremdsystemen per Batch-Job oder Webservice abgeglichen werden. Oder generell ein System, bei dem sich regelmäßig andere Informationen (wie beispielsweise Preise – also noch brisanter) zu irgendeiner Entität ändern und nicht blind in die Datenbank gespielt werden können. Stellen Sie sich vor, das Fremdsystem produziert versehentlich einen Fehler und ein Artikel kostet anstatt 1.000€ plötzlich fälschlicherweise nur noch 10€ und das wird dann blind so in die Datenbank gespielt. Das könnte unter Umständen fatale Folgen haben. Also ist man an dieser Stelle doch wieder auf eine konkrete Implementation unter Zuhilfenahme der (zunächst einmal) MasterDataDelegate-Funktionen angewiesen.

    In meinem konkreten Fall ist es so, dass Lieferanten von Artikeln ihre Artikeldatenkorrekturen regelmäßig verschicken. Alle Artikel müssen dann zunächst in eine temporäre Tabelle eingespielt werden, um im Nachhinein die Artikeldatenkorrekturen gegenüber den Bestandsdaten nach bestimmten Verarbeitungsregeln, teilweise aber auch manuell verifizieren zu können (Begründung der Notwendigkeit ähnlich wie bei dem oben beschriebenen Falscher-Preis-Szenario). Es kann also nicht einfach blind in die Datenbank weggeschrieben werden. Sonst könnte ich ja tatsächlich auch gleich direkt ein DB-Skript schreiben. Die Anzahl der Artikel liegt dabei zwischen 5.000 und 60.000. Sie können sich sicher vorstellen, wie die Akzeptanz bei den Kunden ist, wenn sowas zu lange dauert.

    Für den Abgleich von Beständen von Artikeln (welche ich später auch noch bearbeiten muss) wäre die Sache ja ähnlich kritisch, weil die noch viel öfter und von vielen verschiedenen Fremdsystemen stattfinden. Wahrscheinlich war sowas in der Art auch bei hugo der Fall…

    #4440
    Thomas Schiffmann
    Teilnehmer

    Hallo hoeppi,

    ein Datenabgleich als Form einer Schnittstelle zu anderen Systemen oder Akteuren ist schon ein Anwendungsfall, dem man häufiger begegnet. Insbesondere hier sind aber die Anforderungen von Fall zu Fall sehr unterschiedlich, so dass eine generische Implementierung dieser Funktionen schwierig ist. Manche Schnittstellen dieser Art werden über einfache Datenbanksichten oder Datenbankprozeduren realisiert, manche über Messaging-Systeme, manche über – wie Sie schon erwähnt haben – Webservices, und manche wie bei Ihnen über spezielle Dateiformate. Hinzu kommen dann unterschiedliche Kombinationen aus Anforderungen an Datenmenge, Validierungen, Benutzerinteraktion und Zeit, wobei sich die ersten drei natürlich negativ auf letztere auswirken.

    Wenn Sie nun die vollständige Nuclos-Funktionalität (z.B. Regelausführung) benötigen, kommen Sie um die Verwendung der Fassaden (Fassaden sind die server-seitigen Gegenstücke der Delegates – somit könnten Sie die Client-Server-Kommunikation verhindern) nicht herum. Natürlich gibt es in Nuclos auch schnellere Mechanismen für das Löschen/Erstellen/Aktualisieren von Datensätzen, die intern von den Delegates bzw. Fassaden verwendet werden und nur das Schreiben bzw. Löschen der Daten vornehmen.
    Aber auch hier ist fraglich, bis zu welcher Datenmenge man zufriedenstellende Ergebnisse erreicht – für den einen Anwendungsfall müssen es 10.000 Datensätze sein, für den nächsten 1.000.000.

    Insbesondere wenn die Datenmenge nun größer und der Zeitfaktor kritischer wird, geht man selbst in Individualsoftwaresystemen dazu über, diese Funktionen datenbankseitig zu implementieren (siehe hugo), da Objekt-relationale Mapping-Frameworks häufig nicht dafür ausgelegt sind und die Datenbank maximale Performance bietet.

    Je nachdem, welche Anforderungen an den manuellen Datenabgleich in ihrem Anwendungsfall gegeben sind, können Sie natürlich auch eine Kombination aus Datenbankprozeduren und Nuclosfunktionen verwenden. Vielleicht können Sie noch beschreiben, wie der manuelle Abgleich zu erfolgen und wie die manuell abzugleichende Datenmenge ausgewählt wird.

    Viele Grüße
    tsc

    #4443
    Yves Hoeppe
    Teilnehmer

    Danke für die Antwort.
    Also hier ganz konkret die Beschreibung:

    Die Funktionalitäten Direktimport/Standardimport benutze ich dafür, um die Bestandsdaten aus dem jetzigen System in Nuclos einzufügen. Hierbei bin ich jetzt ganz gut gefahren, indem ich mir zwei nahezu identische Definitionen für ein und dieselbe Entität angelegt habe, mit dem einzigen Unterschied, dass die eine Definition den Direktimport, die andere den Standardimport benutzt. Ich lasse den Standardimport so lange durchlaufen, bis alle Abhängigkeiten geprüft wurden. Dann breche ich ihn ab. Bei den Prüfungen treten in der Regel zunächst Fehler auf. Ich bereinige dann nach und nach die zu importierenden Daten um ihre Fehler. Laufen die Plausibilitätsprüfungen am Anfang des Standardimports dann irgendwann ohne Fehler durch, benutze ich den Direktimport, um die Daten dann tatsächlich einzuspielen. Das funktioniert also ganz gut.

    Der 2. Schritt ist, dass ich Daten von Lieferanten bekomme. Diese Daten sind unterschiedlich formatiert (unterschiedliche csv-Definitionen, feste Feldlänge usw.) und je nach Sortiment fällt die Datenmenge unterschiedlich groß aus. Diese Daten werden in eine temporäre DB-Tabelle eingetragen. Leider können nicht alle Felder der DB-Tabelle durch die bloßen CSV-Inhalte bestückt werden. Manche Felder ergeben sich aus Substrings anderer Felder. Manche Felder müssen zusammengesetzt werden usw. Da gibt es nichts, was es nicht gibt. Deswegen habe ich eine Klasse geschrieben und ins Nuclos-Menü eingebunden, die zwischen den verschiedenen Formaten differenziert und die fehlenden DB-Felder „berechnet“… Anschließend werden die Daten in eben diese temporäre Tabelle weggeschrieben. An der Stelle benutze ich eben die MasterDataDelegate-Funktionen und das dauert ziemlich lange.

    Unproblematischer ist der 3. Schritt, bei dem die Felder aus der temporären Tabelle in einer Maske den bereits vorandenen Daten gegenüber gestellt werden. Der Benutzer legt zunächst fest, welche Felder der bereits vorhandenen Daten überschrieben (aktualisiert) werden sollen. Es werden dann alle Artikel durchgegangen. Nur wenn ein neuer Wert vom zugehörigen alten Wert abweicht, muss der Benutzer eingreifen und überhaupt ein Datensatz aktualisiert werden. Daher ist das also nicht das zeitkritische Problem.

    Zeitkritisch ist eigentlich nur Schritt 2.

    #4505
    Thomas Schiffmann
    Teilnehmer

    Hallo hoeppi,

    Deswegen habe ich eine Klasse geschrieben und ins Nuclos-Menü eingebunden, die zwischen den verschiedenen Formaten differenziert und die fehlenden DB-Felder „berechnet“… Anschließend werden die Daten in eben diese temporäre Tabelle weggeschrieben

    Ich fürchte, Sie kommen für die Optimierung dieses Schritts nicht um weitere individuelle Implementierungen herum. Welche Nuclos-Funktionen (Regeln, Validierungen, usw.) benötigen Sie denn konkret für das Schreiben/Löschen der Daten?

    Viele Grüße
    tsc

    #4652
    Yves Hoeppe
    Teilnehmer

    [quote=“tsc“ post=3658]
    Hallo hoeppi,

    Deswegen habe ich eine Klasse geschrieben und ins Nuclos-Menü eingebunden, die zwischen den verschiedenen Formaten differenziert und die fehlenden DB-Felder „berechnet“… Anschließend werden die Daten in eben diese temporäre Tabelle weggeschrieben

    Ich fürchte, Sie kommen für die Optimierung dieses Schritts nicht um weitere individuelle Implementierungen herum. Welche Nuclos-Funktionen (Regeln, Validierungen, usw.) benötigen Sie denn konkret für das Schreiben/Löschen der Daten?

    Viele Grüße
    tsc
    [/quote]

    Hallo,

    auf jeden Fall benötige ich für alle DB-Operationen rund um dieses Thema (Selects, Updates, Creates und Removes) keine Businessrules und Webservices an dieser Stelle. Berechtigung würde da wahrscheinlich auch nicht die Rolle spielen, weil die entsprechenden Menüpunkte in diesem Fall sowieso nicht zu den Kunden ausgeliefert werden.

    Geloggt werden müsste bei Bedarf. Unique-Constraint-Violations sollten erkannt und übersprungen werden. Ansonsten nichts Spektakuläres.

    Ich habe jetzt auch herausgefunden, wie man noch ziemlich komfortabel direkt auf die DB zugreifen kann…


    DbAccess directDBaccess = DataBaseHelper.getDbAccess();
    String statement = "...";
    ResultVO resultvo = directDBaccess.executePlainQueryAsResultVO(statement, 10000);

    Dazu habe ich noch eine Frage: Warum werden die IDs als Double im ResultVO repräsentiert? Nimmt man ein MasterDataVO, gibt es da ja nur getIntId(), aber nicht getDoubleId()…

    Und dann habe ich im Anhang noch einen Vorschlag, wie man vielleicht den MasterDataDelegate erweitern könnte, bestehend aus einem POJO-File, einem *Remote-File und einem *Bean-File… Es geht um eine Select-Optimierung… Die Zeitersparnis kann hier – je nach zusätzlichen SearchConditions der Dependants – enorm sein. Hatte schon Unterschiede von über 30Sekunden bei gleicher Zeilenanzahl (ca. 3.500) der Hauptentität im Vergleich zu dem, was mit dem MasterDataDelegate bisher möglich war, um am Ende dasselbe Ziel zu erreichen…

    Alleine dieser Schritt hat schon ziemlich viel zur Optimierung beigetragen.
    Für Updates, Creates und Removes weiß ich noch nicht recht… Ich habe mal ein bisschen tiefer reingeschaut in die Klassen… Scheinbar wird es da ziemlich schwer, im Rahmen des Frameworks zu bleiben, weil alles auf zeilenweise Prüfungen hinausläuft… Deshalb dann wohl doch wie ganz oben im Code beschrieben…

    MfG,
    hoeppi

    Attachments:
Ansicht von 11 Beiträgen - 1 bis 11 (von insgesamt 11)