En plus de deux décennies de dépannage d'applications JDE personnalisées, je vois régulièrement des formulaires Find/Browse ou Header Detail qui mettent quatre à huit secondes à s'afficher simplement parce que les développeurs accumulent des accès Table I/OOpérations de lecture ou d'écriture dans les tables de la base de données JD Edwards. synchrones vers la F0101Table maîtresse du carnet d'adresses contenant les informations sur les entités comme les clients ou fournisseurs. ou la F4101Table maîtresse des articles contenant les définitions de base de tous les produits dans le système. dans l'événement Dialog Is InitializedÉvénement JDE s'exécutant au démarrage d'un formulaire, avant que l'utilisateur ne voie l'écran.. Ce défaut de conception contourne le mapping natif base de données-vers-grille du moteur JDE, forçant le serveur HTML à attendre des allers-retours sérialisés avec la base de données avant d'afficher le premier pixel.
Pour corriger cela, nous devons passer d'une récupération procédurale synchrone à un report piloté par les événements. Nous allons analyser un exemple concret de Table I/O JDE APPL pour éviter les problèmes de chargement lent en déplaçant les récupérations de validation secondaires hors de l'initialisation du formulaire pour les placer dans l'événement Grid Record Is FetchedÉvénement déclenché chaque fois qu'une ligne de données est récupérée pour être affichée dans une grille.. Ce seul ajustement architectural réduit régulièrement la latence de lancement des formulaires interactifs de 75 % à 80 % tout en gardant le pool de threads JVMJava Virtual Machine, l'environnement qui exécute le serveur web JDE et gère les ressources mémoire. du serveur HTML propre.
La mécanique de la latence de chargement des formulaires
Lorsqu'un utilisateur ouvre une application interactive personnalisée, le moteur JAS traite le cycle de vie de création du formulaire de manière séquentielle. L'événement Dialog Is Initialized bloque entièrement le thread de la couche de présentation jusqu'à ce que chaque ligne synchrone d'Event Rules (ER)Langage de script propriétaire de JD Edwards utilisé pour programmer la logique métier des applications. ait fini de s'exécuter. Si vos développeurs traitent cet événement comme un dépotoir pour la logique de configuration, le client HTML ne peut même pas commencer à dessiner l'écran.
L'exécution de multiples opérations Table I/O comme des boucles 'Fetch Single' ou 'Select/Fetch Next' sur des tables de base lourdes comme l'Address Book Master (F0101) ou l'Item Master (F4101) pendant cette phase de blocage crée un goulot d'étranglement immédiat. Chaque récupération individuelle nécessite un aller-retour du serveur HTML vers le serveur d'entreprise, puis vers le serveur de base de données. Ce comportement "bavard" aggrave la latence réseau, en particulier dans les topologies de cloud hybrideInfrastructure informatique combinant des serveurs privés locaux et des services de cloud public. où les serveurs de base de données et HTML résident dans des sous-réseaux différents.
Pendant que ces allers-retours en base de données se produisent, l'utilisateur final regarde un navigateur web vide ou figé. Le client HTML est bloqué en attendant que le moteur JAS — et, dans les déploiements modernes, le serveur AISApplication Interface Services, serveur permettant d'interagir avec JDE via des services web REST. — termine le traitement synchrone des métadonnées et renvoie la charge utile de données initiale. Tant que cette charge utile n'est pas livrée, le moteur de rendu du navigateur ne peut pas exécuter le JavaScript côté client requis pour dessiner les contrôles du formulaire.
Dans nos audits de performance de systèmes 9.1 migrés vers la version 9.2, une application APPL personnalisée typique non optimisée met huit à douze secondes à se charger lorsqu'elle exécute plus d'une douzaine de lectures de base de données séquentielles avant le rendu du formulaire. Remplacer ces lectures séquentielles par une logique basée sur des ensembles ou un chargement différé (lazy loadingTechnique consistant à ne charger les données qu'au moment où elles sont nécessaires pour l'utilisateur.) est le moyen le plus rapide de faire descendre les temps de chargement sous le seuil d'une à deux secondes.
Isoler les Table IO de la performance de la base de données
Je vois régulièrement des développeurs perdre des jours à ajuster les index de base de données sur des tables à gros volume comme la F0911 ou la F4111 pour résoudre un écran lent. Ils supposent que si l'initialisation d'un formulaire est lente, c'est que la base de données a du mal à trouver les enregistrements. La réalité est contre-intuitive : la base de données fonctionne souvent parfaitement, mais c'est le volume même des allers-retours séquentiels entre le serveur d'entreprise et le moteur de base de données qui tue les performances. Si une application personnalisée exécute un Fetch Single à l'intérieur d'une boucle des centaines de fois pendant le démarrage, même une lecture d'index hautement optimisée prenant quelques millisecondes s'agrège en un délai de plusieurs secondes avant le chargement de la grille.
Ce décalage de latence crée une déconnexion classique entre les DBA et les développeurs JDE. Votre administrateur de base de données examinera Oracle Database ou SQL Server Profiler et signalera zéro problème, pointant une faible utilisation du processeur et des temps d'exécution inférieurs à la milliseconde. Pendant ce temps, vos journaux de serveur HTML JDE et les fichiers jas.log affichent des temps écoulés massifs pour le CallObject KernelProcessus serveur JDE qui exécute la logique métier demandée par l'interface utilisateur web. de l'application associée. Le goulot d'étranglement n'est pas la vitesse de récupération des données au niveau du disque ; c'est la surcharge du réseau et du middlewareLogiciel intermédiaire assurant la communication entre le serveur web, le serveur d'entreprise et la base de données. liée à la gestion de milliers d'opérations de base de données individuelles de manière sérielle.
Pour contourner ce goulot d'étranglement architectural, vous devez éliminer le traitement ligne par ligne pendant l'événement Dialog Is Initialized. Au lieu d'exécuter des instructions Table I/O individuelles dans une boucle d'Event Rules, refactorisez la logique pour utiliser un traitement par lots ou différez le chargement des données auxiliaires. Par exemple, au lieu d'interroger les données transactionnelles F4111 pour chaque ligne d'une grille de 500 enregistrements, récupérez les clés uniques dans un cache JDEMémoire temporaire stockant des données souvent utilisées pour éviter des requêtes répétées vers la base de données. une seule fois au démarrage du formulaire, réduisant ainsi des centaines d'allers-retours en base de données à une seule recherche en mémoire.
Placement stratégique des événements pour les Table IO
Placer des boucles Fetch Single lourdes dans l'événement Dialog Is Initialized est le moyen le plus rapide de geler une session client HTML pendant cinq à dix secondes. À ce stade du moteur d'exécution JDE, le système prépare encore la structure du formulaire, ce qui signifie que l'utilisateur voit un écran vide pendant que la base de données travaille. Déplacer ces opérations de base de données non bloquantes vers l'événement Post Dialog Is InitializedÉvénement s'exécutant juste après l'affichage initial du formulaire pour des traitements non bloquants. garantit que la structure du formulaire s'affiche immédiatement, donnant à l'utilisateur la confirmation visuelle que l'application est réactive.
Un échec architectural courant dans les applications JDE personnalisées est la récupération de données auxiliaires au niveau de la grille lors du chargement initial du formulaire. Pour une grille affichant 50 enregistrements, l'exécution de recherches de table individuelles pendant l'initialisation force des dizaines d'allers-retours séquentiels en base de données. Les développeurs doivent décharger ce travail vers les événements Grid Record is Fetched ou Write Grid Line-Before, qui s'exécutent dynamiquement à mesure que chaque ligne est remplie. Cela réduit la taille de la charge utile initiale et évite les timeouts du serveur JAS.
Dans les formulaires Find/Browse, les développeurs écrivent souvent des boucles manuelles Select et Fetch Next à l'intérieur de l'événement du bouton Find pour filtrer les résultats de la grille. Cela contourne la gestion native des curseurs de base de données du moteur JDE. L'exécution de la fonction système Set SelectionFonction système JDE permettant de filtrer dynamiquement les données récupérées par une requête SQL. dans l'événement Clear Screen Before Find permet au moteur JDE natif d'ajouter des clauses WHERE personnalisées directement à l'instruction SELECT principale, laissant l'index de la base de données faire le gros du travail.
Pour les formulaires header/detail multi-onglets, charger les enregistrements des tables enfants pour tous les onglets lors de l'ouverture initiale est une taxe de performance inutile. Dans un écran de saisie standard F4211 ou F4311, un utilisateur peut n'inspecter les onglets secondaires que dans une petite fraction des sessions, généralement moins de 15 %. La mise en œuvre d'une récupération conditionnelle — où les lectures détaillées sur des tables comme la F42119 ne sont déclenchées que lorsque l'utilisateur clique sur une page d'onglet spécifique — réduit la surcharge d'exécution SQL initiale à une seule requête légère.

Refactorisation d'un exemple de Table IO APPL personnalisé
J'ai récemment audité une application personnalisée de consultation des commandes ouvertes F4211 où les utilisateurs subissaient un délai pénible à chaque ouverture du formulaire de recherche. La cause profonde était un anti-pattern JDE classique : le développeur avait placé une boucle manuelle Select/Fetch Next dans l'événement Dialog Is Initialized pour récupérer les noms des clients dans l'Address Book Master (F0101) et les codes d'explication fiscale dans les Address Book Phone Numbers (F0116) pour chaque commande client du système avant même que la grille ne s'affiche. Ce matraquage procédural de la base de données contourne complètement l'efficacité du middleware EnterpriseOne.
Pour corriger cela, nous avons supprimé les Table I/O procédurales des Event Rules et refactorisé la Business View principale de l'application. En remplaçant la vue plate F4211 par une simple jointure externe gauche (left outer join)Opération SQL liant deux tables en incluant tous les enregistrements de la table de gauche. entre F4211 et F0101/F0116, le moteur de base de données gère la jointure relationnelle en une seule opération SQL. Ce changement de conception délègue le travail lourd à l'optimiseur de requête de la base de données, éliminant des centaines d'allers-retours réseau individuels entre le serveur HTML, le serveur d'entreprise et le serveur de base de données.
Lorsqu'une jointure de table complexe n'est pas réalisable en raison de mappings entre différentes sources de données ou d'une logique métier personnalisée volatile, la solution de repli correcte consiste à déplacer les Table I/O vers l'événement Grid Record is Fetched. Contrairement aux événements d'initialisation qui traitent l'ensemble du jeu de données à l'avance, cet événement s'exécute de manière différée (lazy), ne se déclenchant que pour les lignes actuellement visibles à l'écran. Si la taille de page de votre grille est définie sur les 50 enregistrements standard, JDE exécutera exactement 50 récupérations au lieu de scanner toute la table F4211.
L'application de ce modèle de refactorisation au formulaire de consultation F4211 a donné des résultats immédiats et mesurables. Le temps de chargement initial du formulaire est passé de plus de six secondes à moins d'une demi-seconde pour une page de grille standard de 50 lignes. Ce simple changement réduit considérablement l'utilisation du pool de threads de la base de données sur votre serveur d'entreprise, libérant des ressources pour les utilisateurs interactifs simultanés sur l'instance HTML.

Optimisation du chargement de la grille et tables virtuelles
Les développeurs négligent fréquemment la propriété de grille "Page-at-a-Time", ce qui donne des APPL qui tentent d'extraire des dizaines de milliers d'enregistrements de la F4211 dans la mémoire du serveur web HTML lors du lancement initial. L'activation du traitement Page-at-a-Time limite la récupération initiale de la base de données à la taille de la page de la grille — généralement 10 à 20 lignes — et n'interroge les enregistrements suivants que lorsque l'utilisateur clique sur le bouton "Suivant". Ce seul changement de propriété stabilise immédiatement l'utilisation de la mémoire JVM sur vos instances WebLogic ou WebSphere pendant les pics d'activité du matin.
Les Business Views JDE standard échouent lorsque vous avez besoin de jointures multi-tables complexes, de requêtes union ou d'agrégations sur des tables comme F4101, F41021 et F4102. Au lieu d'écrire des instructions Table I/O imbriquées dans l'événement Grid Record is Fetched pour résoudre ces champs, vous devriez construire une vue de base de données native au niveau de SQL Server ou Oracle Database et la mapper en tant que table virtuelle JDE via l'Object Management Workbench (OMW)L'outil central de JD Edwards pour le développement et la gestion du cycle de vie des objets.. Cette table virtuelle permet au middleware de base de données JDE d'exécuter une seule instruction SQL hautement optimisée plutôt que de forcer le serveur JAS à coordonner plusieurs opérations Table I/O séquentielles.
La consolidation de votre couche d'accès aux données dans une table virtuelle réduit les allers-retours en base de données de 80 % à 90 % sur les écrans transactionnels à haut volume comme la saisie de commandes clients personnalisée ou les APPL de consultation d'inventaire. Dans un projet récent, le remplacement de plusieurs récupérations Table I/O imbriquées dans la F41021 et la F4105 par une seule table virtuelle a réduit le temps de chargement d'un écran de consultation personnalisé de plus de huit secondes à moins d'une demi-seconde. Cette approche déplace le travail lourd d'indexation et de jointure vers le moteur de base de données, là où il doit être, gardant votre moteur logique EnterpriseOne propre et réactif.
Profilage du chargement de formulaire avec Server Manager
Résoudre un délai de chargement de formulaire de plusieurs secondes nécessite de dépasser les suppositions et d'ouvrir le fichier jdedebug.logFichier journal capturant les instructions SQL et les appels techniques pour faciliter le dépannage.. Ce journal est votre principal outil de diagnostic pour identifier les instructions Table I/O exactes qui bloquent l'interface utilisateur. En lançant une trace CallObject Kernel dans Server Manager, vous pouvez capturer la durée exacte en millisecondes de chaque instruction SQL exécutée pendant les événements Dialog is Initialized et Post Dialog is Initialized. Ce suivi en temps réel expose la surcharge de traitement des fonctions métier personnalisées avant même que le formulaire ne s'affiche sur l'écran de l'utilisateur.
Lors de l'analyse de la trace, recherchez les motifs répétés SELECT ... FROM PRODDTA.F0101 ou PRODDTA.F4101 se produisant dans la même seconde, chacun interrogeant différents numéros d'adresse ou d'article. Ce motif indique une boucle exécutant des Table I/O sur une base ligne par ligne dans la grille, plutôt que d'utiliser une seule récupération basée sur un ensemble ou une vue de base de données. L'élimination de ces appels SQL itératifs peut immédiatement compresser un décalage de base de données d'une demi-seconde à quelques millisecondes, réduisant considérablement le temps passé dans le CallObject Kernel.
Une fois que vous avez refactorisé les événements incriminés, vous devez verrouiller ces gains avant votre prochaine mise à jour de Tools ReleaseVersion du socle technologique de JD Edwards qui gère l'infrastructure et les fonctions système.. Utilisez l'application Performance Monitor (P980060) pour établir une base de référence claire du traitement des transactions pour vos applications interactives critiques. La comparaison de ces mesures avant et après la mise à jour empêche toute régression, garantissant qu'une mise à jour Tools vers la 9.2.8 ou au-delà ne réintroduise pas silencieusement de la latence via un comportement modifié du middleware ou des changements de pilotes de base de données. Exécutez ces tests de référence sous une charge simulée de 50 utilisateurs simultanés pour vérifier la stabilité de vos modifications.
Si vous refactorisez du code APPL hérité pour répondre aux normes de performance 9.2.8, nos autres guides techniques sur la gestion du cache BSFNBusiness Function, module de code contenant de la logique métier complexe exécutée sur le serveur d'entreprise. et les extensions de formulaire basées sur AIS offrent des plongées plus profondes dans l'optimisation des environnements EnterpriseOne.