In hochvolumigen Distributionsumgebungen ist die Implementierung eines JDE BSFNEine Business Function in JD Edwards, die spezifische Geschäftslogik in C oder NER ausführt. Transaction BoundaryDefiniert den Anfang und das Ende einer logischen Arbeitseinheit, die entweder vollständig erfolgreich ist oder komplett zurückgesetzt wird. Beispiels zur Vermeidung von Teil-Updates von entscheidender Bedeutung; ein einzelner verwaister F4211Die zentrale Datenbanktabelle in JD Edwards für Verkaufsauftragsdetails.-Datensatz ohne entsprechende F41021Die JD Edwards Tabelle für Bestandsmengen pro Artikel und Lagerort.-Bestandsverpflichtung kann den gesamten Versandlauf eines Lagers stoppen. Wenn benutzerdefinierte C-BSFNsIn der Programmiersprache C geschriebene Geschäftsfunktionen innerhalb von JD Edwards. oder NERsNamed Event Rules; eine JDE-eigene Programmiersprache, die grafisch erstellt und in C-Code umgewandelt wird. Schreibvorgänge in mehreren Tabellen durchführen, gehen Entwickler oft davon aus, dass das Aktivieren des Kontrollkästchens "Transaction Processing" in den APPLEine interaktive Anwendung in JD Edwards, die über eine grafische Benutzeroberfläche bedient wird.- oder UBEUniversal Batch Engine; ein Programm zur Stapelverarbeitung oder Berichterstellung im Hintergrund.-Eigenschaften ausreicht, um die Transaktionsgrenze zu erben. Das ist nicht der Fall. Ohne explizite Weitergabe der Transaktionsgrenze bis auf die Ebene der Master Business Function (MBF)Eine zentrale Logikeinheit, die komplexe Datenbankoperationen und Validierungen für ein Geschäftsobjekt bündelt. wird bei einem Datenbank-Timeout oder einem Standard-jdeCallBf-Fehler mitten im Prozess der Header festgeschrieben (Commit)Der Vorgang, bei dem alle während einer Transaktion vorgenommenen Änderungen dauerhaft in der Datenbank gespeichert werden., aber der Detail-Datensatz zurückgerollt (Rollback)Das Rückgängigmachen aller Änderungen einer Transaktion, falls ein Fehler auftritt, um die Datenintegrität zu wahren., was zu korrupten Ledger-Zuständen führt.

Die Durchsetzung der transaktionalen Integrität über diese Operationen hinweg erfordert die direkte Zuordnung Ihrer manuellen Rollback-Logik zur aktiven Transaktions-ID (hUser->hTxnEin technischer Zeiger im C-Code, der die Verbindung zwischen einem Benutzer und einer aktiven Datenbanktransaktion identifiziert.). Indem Sie Ihre JDB_OpenTableEine API-Funktion in JD Edwards, die eine Verbindung zu einer Datenbanktabelle herstellt.- und jdeCallBf-APIsApplication Programming Interfaces; Schnittstellen, die den Datenaustausch und Funktionsaufrufe zwischen Softwarekomponenten ermöglichen. explizit an den übergeordneten Transaktionskontext innerhalb Ihres benutzerdefinierten C-Codes binden, garantieren Sie, dass bei einem Fehler beim Schreiben in die F41021 der gesamte Stapel – einschließlich aller F4211-Inserts – atomarBezieht sich auf eine Operation, die entweder vollständig ausgeführt oder bei einem Fehler komplett rückgängig gemacht wird. zurückgerollt wird. Dieser Ansatz eliminiert das Risiko einer stillschweigenden Datenkorruption während Spitzenzeiten mit hoher ParallelitätDie Fähigkeit eines Systems, mehrere Aufgaben oder Datenbankzugriffe gleichzeitig zu verarbeiten., wenn Datenbank-Sperren am volatilsten sind.

Die Mechanik von JDE Transaction Boundaries

Entwickler verwechseln JDE-Transaktionsverarbeitung oft mit nativen Datenbanktransaktionen, was zu verwaisten Datensätzen in Tabellen wie der F0911 während hochvolumiger Batch-Läufe führt. JDE EnterpriseOne verwaltet Transaktionsgrenzen auf der MiddlewareSoftware, die als Vermittlungsschicht zwischen Anwendungen, Datenbanken und dem Betriebssystem dient.-Ebene mithilfe der JDB-APIDie spezifische Programmierschnittstelle von JD Edwards für Datenbankzugriffe., anstatt sich auf direkte Konstrukte auf Datenbankebene zu verlassen. Diese architektonische Abstraktion bedeutet, dass die EnterpriseOne-Datenbank-Middleware (JDBNETDie proprietäre Datenbank-Middleware von JD Edwards, die den Zugriff auf verschiedene Datenbanksysteme abstrahiert.) den Commit- und Rollback-Lebenszyklus steuert und die C-Business-Functions von der zugrunde liegenden Datenbankplattform isoliert, unabhängig davon, ob Sie auf Oracle Database 19cEin modernes relationales Datenbankmanagementsystem, das häufig als Backend für JD Edwards EnterpriseOne dient. oder Microsoft SQL Server arbeiten. Standardmäßig arbeitet JDE im Auto-Commit-Modus, bei dem jeder einzelne JDB_InsertTable- oder JDB_UpdateTable-Aufruf sofort in der Datenbank festgeschrieben wird.

Die Aktivierung des manuellen Commits erfordert die explizite Bindung der Datenbank-Benutzersitzung an eine aktive Transaktionsgrenze unter Verwendung der JDB_OpenTable-API mit Transaktionsoptionen. Insbesondere übergeben Sie das Flag JDB_COMMIT_MANUALEin Flag in der JDE-Programmierung, das den automatischen Datenbank-Commit deaktiviert und manuelle Kontrolle ermöglicht. innerhalb der Transaction Boundary-Konfiguration des Table-Open-Aufrufs. Dies weist die JDB-Middleware an, die Datenbank-Sperren zu halten und die SQL-Operationen im Transaktions-Workspace des aktuellen Threads in die Warteschlange zu stellen. Der Datenbank-Commit erfolgt erst, wenn die Runtime-Engine auf einen expliziten JDB_CommitUser-Aufruf stößt, während jeder Fehler einen JDB_RollbackUser auslöst, um alle in der Warteschlange befindlichen Operationen rückgängig zu machen.

Die Transaktionsgrenze erstreckt sich über den gesamten Call-StackDie hierarchische Abfolge von Funktionsaufrufen während der Programmausführung., was bedeutet, dass untergeordnete BSFNs den Transaktionskontext der aufrufenden Applikation (APPL) oder Batch-Engine (UBE) erben können. Wenn eine interaktive Anwendung wie Sales Order Entry (P42101) eine Transaktion initiiert, kann jede Business Function, die so konfiguriert ist, dass sie im selben Ausführungsthread läuft, der aktiven Transaktion beitreten. Wenn Sie die übergeordnete BSFN so konfigurieren, dass sie mit aktivierter Transaktionsverarbeitung läuft, gibt JDE die aktive Transaktions-ID automatisch an verschachtelte Business Functions weiter. Dies stellt sicher, dass ein Fehler in einer tief verschachtelten Child-Funktion wie F4211FSEndDoc einen vollständigen Rollback der gesamten logischen Arbeitseinheit auslöst.

Multi-Table BSFN Transaction Rollback Flow

Anatomie eines fehlgeschlagenen Multi-Table-Updates

In einer Standardanpassung der Verkaufsauftragserfassung schreibt ein Entwickler oft eine benutzerdefinierte C-Business-Function, um sowohl das Einfügen der Detailzeile als auch die Bestandsverpflichtung zu verarbeiten. Ein klassisches Fehlerszenario tritt auf, wenn diese benutzerdefinierte BSFN erfolgreich einen Datensatz in die Sales Order Detail Tabelle (F4211) einfügt, aber während der anschließenden Bestandsverpflichtung in der Item Location Tabelle (F41021) aufgrund einer Datensatzsperre oder einer Limitüberschreitung fehlschlägt. Ohne eine aktive Transaktionsgrenze schreibt die Datenbank den F4211-Datensatz sofort fest, während das F41021-Update verloren geht, was zu sofortigen Differenzen in der Bestandsabstimmung führt. Dies hinterlässt die Verkaufsauftragszeile in einem "festgeschriebenen" Zustand, während die physische Bestandsallokation unberührt bleibt.

Diese Teil-Updates umgehen die Standard-Integritätsprüfungen von JDE, was bedeutet, dass Standard-UBEs wie Repost Active Sales Orders (R42995) oder Item Ledger/Account Ledger Integrity (R41543) die Fehler zwar markieren, aber die Ursache nicht automatisch beheben können. Dies zwingt CNCsConfigurable Network Computing; Experten für die Systemadministration und Architektur von JD Edwards Umgebungen. und Datenbankadministratoren dazu, manuelle SQL-Korrekturen durchzuführen, um verwaiste Datensätze in engen Wartungsfenstern zu bereinigen. In einem hochvolumigen Distributionszentrum, das 8.000 bis 12.000 Versandzeilen pro Stunde verarbeitet, führen selbst Bruchteile von Prozenten an Fehlerraten täglich zu mehreren schwerwiegenden Datenbankdiskrepanzen.

Sich auf die Fehlerbehandlung auf Anwendungsebene zu verlassen, um vorherige Schreibvorgänge rückgängig zu machen – wie das Schreiben manueller DELETE-SQL-Anweisungen im Event "Post Button Clicked" einer interaktiven Anwendung (APPL) – ist höchst unzuverlässig. Wenn die Netzwerkverbindung abbricht oder die Web-Sitzung des Benutzers auf dem JAS-ServerJava Application Server; die Komponente, die die JD Edwards Anwendung für Webbrowser bereitstellt. mitten im Prozess abläuft, wird dieser Bereinigungscode nie ausgeführt. Die einzige absolut sichere Lösung besteht darin, die Datenbank-Engine den Rollback automatisch verwalten zu lassen, um sicherzustellen, dass die F4211- und F41021-Operationen an eine einzige, atomare Datenbanktransaktion gebunden sind.

Konfiguration von BSFNs für die Transaktionsverarbeitung

In der OMWObject Management Workbench; die zentrale Entwicklungsumgebung zur Verwaltung von Objekten in JD Edwards. erfordert die Aktivierung von Transaktionsgrenzen mehr als nur das Schreiben von sauberem C-Code oder NER-Zeilen. Sie müssen das Business-Function- oder NER-Objekt auswählen, seine Design-Eigenschaften öffnen und explizit das Flag Transaction Processing aktivieren. Ohne diese Metadaten-Konfiguration in der Tabelle F9860 ignoriert die Runtime-Engine jegliche internen manuellen Rollback-APIs oder Commit-Anweisungen auf Systemebene vollständig. Sie fällt in den Auto-Commit-Modus für jede einzelne SQL-Anweisung zurück, was Ihre Fehlerbehandlungslogik nutzlos macht.

Bei der Ausführung dieser BSFN aus einer interaktiven Anwendung (APPL) muss das übergeordnete Formular den Transaktionskontext herstellen. Sie müssen die Formulareigenschaften im FDAForm Design Aid; das Werkzeug zur Entwicklung von interaktiven Benutzeroberflächen in JD Edwards. öffnen und die Eigenschaft 'Transaction' aktivieren. Wenn bei Ihrem übergeordneten Formular, wie z. B. einem Header Detail oder Power Form, diese Eigenschaft nicht aktiviert ist, wird jede aus den Ereignissen des Formulars aufgerufene BSFN in einer eigenen unabhängigen Datenbankverbindung ausgeführt und Daten sofort nach der Ausführung festgeschrieben, unabhängig von nachfolgenden Formularfehlern.

Für Batch-Prozesse, die über eine Universal Batch Engine (UBE) laufen, gilt eine ähnliche Regel, um Commits mitten im Lauf zu verhindern. Sie müssen das Kontrollkästchen 'Transaction Processing' in den Eigenschaften des Report-Templates oder den spezifischen Section-Eigenschaften im RDAReport Design Aid; das Werkzeug zur Erstellung von Batch-Berichten und Prozessen in JD Edwards. aktivieren. In einer typischen Multi-Section-UBE, die 5.000 bis 15.000 Verkaufsauftragszeilen verarbeitet, bedeutet das Versäumnis, dieses Feld zu aktivieren, dass ein Datenbankfehler in der Mitte des Batches die erste Hälfte der Datensätze dauerhaft festgeschrieben lässt, was eine manuelle Datenabstimmung erfordert, die Stunden dauern kann.

Schließlich müssen Sie beim Verschachteln von Child-Business-Functions innerhalb Ihrer Master-Logik den Parameter 'Include in Transaction' während des Call-Object-Befehls konfigurieren. Wenn Sie diesen Schritt auslassen, erzeugt die Middleware eine separate, automatisch committende Datenbank-Sitzung für diese spezifische Child-BSFN. Dies bricht die einzelne Arbeitseinheit auf und ermöglicht es Child-Updates, festgeschrieben zu werden, selbst wenn die übergeordnete Transaktion anschließend aufgrund eines Validierungsfehlers einen Rollback auslöst.

JDE Commit Modes and Transaction Scopes

Der BSFN-Code: Implementierung des manuellen Rollbacks

Benutzerdefinierte C-BSFNs erfordern absolute Disziplin im Umgang mit der hUserEin Datenstruktur-Handle in JDE, das Benutzerkontext und Sitzungsinformationen für Datenbankoperationen speichert.-Datenstruktur über alle internen Funktionen hinweg. Wenn Sie JDB_OpenTable oder JDB_InsertTable aufrufen und ein generisches oder NULL-User-Handle anstelle des aktiven, transaktionsfähigen hUser übergeben, wird die Transaktionsgrenze sofort unterbrochen. Ich habe mehrere benutzerdefinierte Bestandsallokationsprogramme korrigiert, bei denen Entwickler diese Handles vermischt haben, was dazu führte, dass F41021-Updates sofort festgeschrieben wurden, während die entsprechenden F4211-Zeilen bei einem Fehler zurückgerollt wurden. Um dies zu verhindern, übergeben Sie genau dasselbe lpBhvrCom->hUser-Handle an jede verschachtelte Unterfunktion.

Jeder einzelne Datenbank-API-Aufruf innerhalb Ihrer logischen Arbeitseinheit muss validiert werden. Wenn ein JDB_UpdateTable oder JDB_InsertTable fehlschlägt – was bedeutet, dass JDEDB_PASSED != apiStatus ist – muss die BSFN die nachfolgende Logik umgehen und sofort einen JDB_RollbackTransaction-Aufruf ausführen. Dieser einzige API-Aufruf weist die Datenbank-Engine an, die nicht festgeschriebenen Schreibvorgänge im Transaktionsprotokoll zu verwerfen, um zu verhindern, dass unvollständige Daten Kern-Tabellen wie F0911 oder F03B11 korrumpieren. In unseren Tests führte das Auslassen dieser Prüfung bei nur einem kleinen Bruchteil der Tabellenschreibvorgänge in etwa 10 % bis 15 % der Fälle zu Teil-Commits unter Spitzenlast.

Nur wenn jede Datenbankoperation in der Sequenz JDEDB_PASSED zurückgibt, sollte die BSFN JDB_CommitTransaction ausführen, um die Änderungen dauerhaft zu speichern. Das Versäumnis, explizit zu committen oder einen Rollback durchzuführen, oder das Versäumnis, das Transaktions-Handle über JDB_FreeUser freizugeben oder Tabellen ordnungsgemäß zu schließen, hinterlässt offene Cursor und Sperren in der Datenbank. In hochvolumigen Umgebungen mit 40.000 bis 60.000 Transaktionen pro Stunde eskalieren diese verwaisten Datenbanksitzungen schnell zu Tabellensperren, die den gesamten Call-Stack auf Tabellen wie der F41021 blockieren. Stellen Sie sicher, dass Ihr Bereinigungsblock immer ausgeführt wird, unabhängig davon, ob die Transaktion erfolgreich war oder fehlgeschlagen ist.

Entwurf eines strengen Test-Fehlerpfads

Softwareentwickler machen oft den Fehler, nur erfolgreiche Transaktionsflüsse zu testen, wodurch die Rollback-Logik bis zu einem Produktionsabsturz völlig ungeprüft bleibt. Die Validierung einer Transaktionsgrenze erfordert, dass Sie absichtlich einen Datenbankfehler unmittelbar nach dem ersten Tabellenschreibvorgang, aber vor dem endgültigen Commit erzwingen. In einer Standard-Verkaufs- oder Bestandsintegration bedeutet dies, den primären Tabellenschreibvorgang erfolgreich durchlaufen zu lassen und dann sofort einen Fehler zu injizieren, der den Prozess stoppt, bevor die Transaktionsgrenze geschlossen wird.

Das Injizieren eines Fehlers aufgrund eines doppelten Schlüssels in eine sekundäre Tabelle wie das Journal Entry Functional File (F0911) ist der zuverlässigste Weg, diesen Rollback auf Datenbankebene auszulösen. Sie können beispielsweise vorab einen Datensatz mit einer bestimmten Belegnummer, einem Typ und einer Firma in die F0911 einfügen und dann Ihre benutzerdefinierte Business Function mit genau diesen Schlüsseln ausführen. Wenn die Standard-JDE-Master-Business-Function versucht, die passenden GL-Zeilen einzufügen, wird die Datenbank eine Verletzung des eindeutigen SchlüsselsEin Datenbankfehler, der auftritt, wenn versucht wird, einen Datensatz mit einem bereits existierenden Identifikationsschlüssel einzufügen. (SQL State 23505) auslösen, was den gesamten Transaktionsstapel zum Scheitern bringt.

Nach dem Auslösen dieses erzwungenen Fehlers müssen Entwickler die Datenbank direkt abfragen, um sicherzustellen, dass keine verwaisten Datensätze in einer der Zieltabellen vorhanden sind. Sie sollten SQL-Abfragen sowohl gegen die primären als auch gegen die sekundären Tabellen ausführen, um zu bestätigen, dass die ursprünglichen Schreibvorgänge vollständig zurückgerollt und nicht teilweise festgeschrieben wurden. Wenn Sie auch nur einen einzigen Header-Datensatz ohne die entsprechenden Detailzeilen finden, ist Ihre Transaktionsgrenzen-Konfiguration fehlerhaft.

Automatisierte Testskripte sollten sowohl den Erfolgspfad als auch diesen Fehlerpfad validieren, um sicherzustellen, dass zukünftige ESUsElectronic Software Updates; Software-Patches von Oracle zur Fehlerbehebung oder Funktionserweiterung in JD Edwards. oder Tools-Upgrades die Konfiguration der Transaktionsgrenzen nicht stillschweigend unterbrechen. Das Ausführen dieser automatisierten Regressionstests in Ihrer DV920-Umgebung nach der Installation eines Tools-Updates verhindert unerwartete Datenkorruption, wenn der Code in die Produktion migriert wird.

Auswirkungen auf Performance und Sperren

Das Ausdehnen einer Transaktionsgrenze über mehrere Business Functions oder lang laufende interaktive Anwendungen hinweg wirkt sich direkt auf die Datenbank-Parallelität aus. Wenn eine Transaktion zu lange offen gehalten wird, hält das RDBMSRelational Database Management System; Software zur Verwaltung von Daten in Tabellenform, wie Oracle oder SQL Server. exklusive Datenbank-Sperren auf kritische Indexbereiche und Zeilen, was andere Prozesse daran hindert, Lese- oder Aktualisierungsvorgänge auf denselben Datensätzen auszuführen. In hochvolumigen Distributionsumgebungen summiert sich diese Latenz schnell und verwandelt einen Schreibvorgang von unter einer Sekunde in einen mehrsekündigen Engpass.

Das Sperren stark frequentierter Tabellen wie F41021 oder F0911 über längere Zeiträume führt dazu, dass parallele Benutzersitzungen blockiert werden, was zu den gefürchteten 60-sekündigen Timeouts des JAS-Webclients führt. Beispielsweise wird eine benutzerdefinierte Verkaufsauftragsanwendung, die eine exklusive Sperre auf einen F41021-Datensatz hält, während sie auf eine externe API-Validierung wartet, jeden anderen Benutzer einfrieren, der versucht, den Versand zu bestätigen oder Bestände für dieselbe Artikel-Filial-Kombination zu verpflichten. Die resultierenden Blockierzeiten kaskadieren durch den Call-Stack und zwingen den HTML-Server, aktive Benutzersitzungen zu beenden.

Um diese Engpässe zu vermeiden, müssen Entwickler den Transaktionsumfang so eng wie möglich halten, indem sie alle Nicht-Datenbank-Validierungen durchführen, bevor sie die Transaktionsgrenze öffnen. Rufen Sie keine Stammdaten ab, validieren Sie keine Benutzerberechtigungen und führen Sie keine komplexen String-Manipulationen innerhalb des jdeTextStartTransaction-Blocks aus. Schließen Sie diese Operationen zuerst ab, überprüfen Sie die Datenintegrität und initiieren Sie die Transaktion erst unmittelbar vor dem Ausführen des ersten Datenbank-Inserts oder -Updates.

Die Überwachung der Eskalation von Datenbank-Sperren ist unerlässlich, wenn transaktionsfähige BSFNs für die hochvolumige Batch-Verarbeitung skaliert werden. Wenn eine UBE 5.000 bis 15.000 Bestandsanpassungen verarbeitet, können SQL Server oder Oracle Database Sperren auf Zeilenebene zu Seiten- oder Tabellensperren eskalieren, um Speicher zu sparen. Diese Eskalation lähmt parallele Ausführungswarteschlangen vollständig und verwandelt einen Multi-Threaded-Batch-Lauf in eine serialisierte Warteschlangenausführung in Zeitlupe.

Die Verwaltung von BSFN-Transaktionsgrenzen ist nur der erste Schritt zur Stabilisierung von 9.2-Umgebungen. Um Speicherlecks oder Datenkorruption in hochvolumigen Batch-Prozessen zu verhindern, sollten Sie auch die zugrunde liegenden Speicherallokationsmuster in Ihrem benutzerdefinierten C-Code untersuchen und sicherstellen, dass alle allokierten Pointer explizit freigegeben werden, bevor der Thread endet.