Pufferung bei Schreibenden BAPIs
Verwendung
Um es externen Systemen zu ersparen, jeweils eine eigene Datenpufferung zu definieren, sollten in allen schreibenden (d.h. erstellenden und verändernden) BAPIs vorgefertigte Pufferungsmechanismen implementiert werden.
SAP-intern gilt dies insbesondere für BAPIs ab Release 4.6A. Wenn Sie eine Pufferung für BAPIs auf einem früheren Releasestand implementieren möchten, sollten Sie zunächst mit einem BFA AG-Ansprechpartner Kontakt aufnehmen.
Für BAPIs können die allgemein im R/3-System gebräuchlichen Mechanismen zur Pufferung von Anwendungsdaten eingesetzt werden. Vom BAPI zu erstellende bzw. zu ändernde Daten werden dabei nicht im Puffer des Verbuchers angelegt, sondern zunächst im Puffer der BAPI-Funktionsbausteingruppe gesammelt. Anschließend wird der gesamte Pufferinhalt gemeinsam, zu einem gegebenen Zeitpunkt verbucht.
Dies hat folgende Vorteile:
Die Verbuchung einzelner Operationen wird verzögert und kann gemeinsam erfolgen. Durch Techniken wie Array-Insert kann ein erheblicher Performancegewinn erzielt werden. Im ungepufferten Fall dagegen muß jede Änderung einzeln verbucht werden.
Bei der ersten Änderung werden die Daten von der Datenbank in den Puffer gelesen und die Änderung im Puffer durchgeführt. Bei einer weiteren Operation wird erkannt, daß die Daten bereits im Puffer vorhanden sind und die Änderung ebenfalls im Puffer durchgeführt. Im ungepufferten Fall müßte die erste Änderung verbucht werden bevor eine zweite durchgeführt werden kann.
BAPIs mit Pufferung eignen sich insbesondere für Situationen, in denen über Application Link Enabling (ALE) Massendaten zwischen Systemen ausgetauscht werden sollen.
Über die Pufferungstechnik ist es möglich, Anwendungsinstanzen in der ALE-Schicht einzeln zu bearbeiten, jedoch die Verbuchung der Instanzen weiterhin gemeinsam durchzuführen. Im Gegensatz zu Multiple-BAPIs, z.B. SaveReplicaMultiple(), ermöglicht diese Vorgehensweise auch eine Fehlerbehandlung individueller Instanzen.
Integration
Aufgrund der beschriebenen Vorteile der Pufferung läßt sich das seit Release 4.0 verwendete
Transaktionsmodell für BAPIs ohne Commit folgendermaßen erweitern:
Folgende Graphik veranschaulicht zunächst das Transaktionsmodell für BAPIs ohne Pufferung.

Das Transaktionsmodell für BAPIs mit Pufferung ist in folgender Abbildung illustriert.

Der Pufferungsmechanismus von BAPIs muß implizit sein, d.h. die Steuerung der Pufferung darf nicht Aufgabe des Aufrufers sein. Ein aufrufendes Programm muß beispielsweise ein Create()- oder Change()-BAPI mit Pufferung genauso verwenden können wie ein entsprechendes BAPI ohne Pufferung; das Verbuchen des Pufferinhalts erfolgt implizit im R/3.
Wurde eine Pufferung für einen Business-Objekttyp implementiert, müssen alle schreibenden BAPIs dieses Business-Objekttyps ebenfalls mit Pufferung implementiert werden.
Wenn an einem Business-Objekttyp schreibende BAPIs mit Pufferung implementiert wurden, hat dies Auswirkungen auf die lesenden BAPIs dieses Objekttyps. Beachten Sie hierzu die Informationen im Abschnitt Aktivitäten (s.u.).
Funktionsumfang
Für BAPIs mit Pufferung sind neben den geltenden Richtlinien zusätzliche Implementierungsschritte bzw. Eigenschaften erforderlich, die im folgenden im Detail beschrieben werden.
Funktionsbausteine für das Verbuchen des Pufferinhalts
Da BAPIs mit Pufferung Instanzen ausschließlich im Puffer erstellen bzw. ändern, müssen Sie einen oder mehrere Funktionsbausteine für das abschließende Verbuchen des Pufferinhalts bereitstellen. Diese Verbuchungsbausteine übergeben den gesamten Pufferinhalt an den Verbucher.
Diese Funktionsbausteine sollten nicht als BAPIs implementiert werden, da diese nur in dem System verwendet werden, in dem auch der Puffer eingesetzt wird.
Als Namenskonvention für diese Funktionsbausteine wird
<Business-Objektname>_SAVEBUFFER vorgeschlagen.
Es dürfen keine Exceptions für Verbuchungsbausteine definiert sein, da diese erst am Ende der Transaktion durchlaufen werden, wenn keine Fehlerbehandlung mehr möglich ist (s.u. Besondere Eigenschaften).
Funktionsbaustein für das Löschen des Pufferinhalts
Um sicherzustellen, daß zu Beginn einer Transaktion der Puffer leer ist, müssen Sie einen Funktionsbaustein für das Löschen des Pufferinhalts zur Verfügung stellen. Dieser Löschbaustein löscht den gesamten Pufferinhalt und beseitigt ggf. vorhandene Sperren der Instanzen. Auch diesen Funktionsbaustein sollten Sie nicht als BAPI implementieren, da er nur in dem System verwendet wird, in dem auch der Puffer eingesetzt wird.
Als Namenskonvention für diesen Funktionsbaustein wird
<Business-Objektname>_CLEARBUFFER vorgeschlagen.
Es dürfen keine Exceptions für Löschbausteine definiert sein, da diese erst am Ende der Transaktion durchlaufen werden, wenn keine Fehlerbehandlung mehr möglich ist (s. u. Besondere Eigenschaften).
BAPIs mit Pufferung müssen besondere Eigenschaften haben, um das erwünschte Pufferungsverhalten zu erzielen. Beispielsweise müssen diese BAPIs im Fehlerfall möglichst robust reagieren, da ein Aufrufer keine Nachbearbeitungen im Puffer durchführen kann. Da die Pufferung implizit erfolgt, stehen einem Aufrufer auch keine BAPIs zur Verwaltung des Puffers zur Verfügung.
Konsistenz des Pufferinhalts
Ein BAPI mit Pufferung muß - bis auf die Verbuchung - alle zur Abarbeitung notwendigen Schritte durchführen. Dabei muß die durch die Anwendung festgelegte Konsistenz aller Instanzen, die im Puffer erstellt oder verändert werden, gewährleistet sein.
Dies bedeutet:
Aufruf der Verbuchungsbausteine
Rufen Sie nach erfolgreichem Abschluß der Pufferoperationen mit dem Kommando
PERFORM <routine> ON COMMIT
eine Formroutine <routine> auf, die ihrerseits den oder die Verbuchungsbaustein(e) aufruft.
Die Verbuchungsbausteine müssen über das Kommando
CALL <Business-Objektname>_SAVEBUFFER IN UPDATE TASK
gerufen werden, um die Ausführung in der Verbuchung zu kennzeichnen.
Durch den Zusatz 'ON COMMIT' im Kommando PERFORM <routine> ON COMMIT wird erreicht, daß die Verbuchung nicht sofort, sondern erst beim nächsten COMMIT WORK-Kommando durchgeführt wird. Auf diese Weise können beliebig viele BAPI-Aufrufe gebündelt werden. Das abschließende COMMIT WORK-Kommando, das vom Aufrufer über das BAPI BapiService.TransactionCommit() durchgeführt wird, führt die Formroutine und damit auch die Verbuchungsbausteine jeweils genau einmal aus. Aus diesem Grund kann in dieser Formroutine und im Verbuchungsbaustein keine Fehlerbehandlung mehr stattfinden.
Subskription des Löschbausteins
Zu Beginn jeder LUW muß der Puffer leer sein. Eventuell im Puffer vorhandene Instanzen, die in einer vorangegangenen LUW bereits verbucht wurden, sind nicht mehr gesperrt und können gegenüber dem Stand auf der Datenbank veraltet sein. Eine erneute Verbuchung dieser Instanzen würde zu Inkonsistenzen führen.
Zum Ende jeder LUW muß demnach der Pufferinhalt durch den Aufruf des Löschbausteins gelöscht werden. Dies kann nur von den BAPIs BapiService.TransactionCommit() bzw. BapiService.TransactionRollback() durchgeführt werden. Um diesen BAPIs die hierzu benötigte Informationen bereitzustellen, müssen BAPIs mit Pufferung ihren Löschbaustein bei dem BAPI BapiService.TransactionCommit() bzw. BapiService.TransactionRollback() subskribieren.
Diese Subskription erfolgt durch den Aufruf des zentralen Funktionsbausteins BUFFER_SUBSCRIBE_FOR_REFRESH, wobei im Parameter NAME_OF_DELETEFUNC der Name des Löschbausteins mitgegeben werden muß.
Kein COMMIT WORK bzw. ROLLBACK WORK-Kommando
BAPIs mit Pufferung dürfen kein COMMIT WORK bzw. ROLLBACK WORK durchführen.
Dokumentation
Jedes BAPI mit Pufferung muß explizit als solches dokumentiert werden.

Beachten Sie folgende wichtige Informationen in Bezug auf das Zusammenwirken von schreibenden BAPIs mit Pufferung und lesenden BAPIs am gleichen Business-Objekt.
Schreibende BAPIs mit Pufferung und lesende BAPIs am gleichen Business-Objekt
Keine Pufferung von gelesenen Instanzen
Sind an einem Business-Objekttyp schreibende BAPIs mit Pufferung implementiert, dürfen lesende BAPIs am gleichen Business-Objekttyp den Puffer nicht verwenden, um von der Datenbank gelesene Daten abzulegen und auf diese Weise weitere Datenbankzugriffe einzusparen.
Da die gelesenen Daten nicht gesperrt sind, würden die entsprechenden Pufferinhalte mit der Zeit veralten. Nachfolgende Leseoperationen würden zuerst auf den Puffer zugreifen und somit die potentiell veralteten Daten lesen, da nur auf der Datenbank nachgelesen wird, wenn sich die zu lesenden Daten nicht im Puffer befinden.
Pufferinstanzen sind "echte" Instanzen
Alle durch schreibende BAPIs im Puffer erstellten oder veränderten Instanzen sind konsistent. Sie stehen anderen verändernden BAPIs zur weiteren Bearbeitung innerhalb derselben LUW zur Verfügung.
Um ein durchgängig analoges Verhalten zu gewährleisten, müssen auch alle lesenden BAPIs die im Puffer, jedoch noch nicht auf der Datenbank, vorhandenen Instanzen als gültige Instanzen betrachten. Lesende BAPIs müssen demnach so implementiert werden, daß sie zunächst versuchen, eine Instanz im Puffer zu lesen und nur wenn diese dort nicht vorhanden ist, in der Datenbank weitersuchen.
Eine Pufferinstanz ist also eine "echte" Instanz, d.h. beispielsweise muß ein BAPI ExistenceCheck() auch im Puffer nach dem Vorhandensein einer Instanz suchen.
Dokumentation lesender BAPIs
Jedes lesende BAPI, das die Pufferung korrespondierender, schreibender Methoden berücksichtigt, muß entsprechend dokumentiert werden.