Have you ever wondered how you can decouple your event publishing/streaming from the actual transaction SAP Netweaver for ABAP? This can be achieved asynchronously by utilizing the bgRFC mechanism.
What is this blog post about?
- This blog post is not a technical introduction to bgRFC concept. You can always refer it in the SAP Help.
- This blog post is not a formal or official recommendation but to share the idea, individual learning and project experience of decoupling event publishing/streaming from the actual transaction using bgRFC.
What do I want to achieve?
- To decouple/separate the LUW of event publishing from the LUW of the actual transaction. Thus, any uncaught exception in the event publishing will not interrupt the successful commit of the actual transaction.
- To improve performance by decoupling/splitting the execution to different work processes. The event publishing is considered less critical and can be executed asynchronously.
- To provide manage the system allocations used to process the event publishing based settings in logon/server group used in the inbound destination as well as bgRFC specific settings at system, application or destination level, thus, preventing it from occupying all available work processes in the system which could result in deterioration of user experience or other critical business processes in your system.
What is bgRFC?
You can use your favourite search engine to look for “sap bgRFC“. Please check your system support patch level of your SAP Netweaver for ABAP environment to match the documentation that you will be referring to. Instead of redefining using my own words, below are the explanation extracted from SAP Help.
“The bgRFC allows applications to record data that is received later by a called application. When the data is received, you must ensure that the data was transferred to the receiver either once only in any order ( transactional) or once only in the order of creation ( queued).”
“bgRFC is the successor to tRFC and qRFC, with significant improvements in terms of performance and functionality.”
The SAP Help provides quite a comprehensive explanation on the following areas of the bgRFC.
- bgRFC: Architecture
- bgRFC: Configuration
- bgRFC: Administration
- bgRFC: Programming
Also a very good introduction about bgRFC can be found in the following page,
And, lastly don’t forget to check on the SAP Support websites for the SAP notes related to your support level to eliminate already known issues that hinder the usage in your application.
The high-level design of my use case:
[Payment Posting] -> [BADI] -> [bgRFC] -> [ABAP proxy] -> [SAP PO] -> [JMS topic]
I have tested on the following environment.
- SAP_BASIS 750 SP0015
- SAP_ABA 750 SP0015
In my Proof of Concept scenario, i would like to publish an event for every payment posting in SAP Banking Services 9.0. During the payment posting, a standard BAdI will be called to generate the payment correspondence. I have implemented the BAdI to the bgRFC, instead of calling the ABAP proxy directly. This allows me to decouple the logical unit of work (LUW) and processing of the event publishing (mapping, formatting and calling the ABAP proxy) asynchronously.
DATA: lx_bgrfc_error TYPE REF TO cx_bgrfc_error. DATA: my_destination TYPE REF TO if_bgrfc_destination_inbound. DATA: my_unit TYPE REF TO if_trfc_unit_inbound. DATA: dest_name TYPE bgrfc_dest_name_inbound. TRY. dest_name = 'WS_BGRFC_INBOUND_PY_POST_NOTF'. "change this according to yr inbound dest name my_destination = cl_bgrfc_destination_inbound=>create( dest_name ). my_unit = my_destination->create_trfc_unit( ). my_unit->disable_commit_checks( ). CALL FUNCTION 'Z_PY_POST_NOTF_OUT' IN BACKGROUND UNIT my_unit EXPORTING i_internal_outbound = i_tab_int_data. CATCH cx_bgrfc_invalid_destination cx_bgrfc_invalid_context INTO lx_bgrfc_error. " log the error inside the application log ... ENDTRY.
As in my scenario, i do not need the publishing of the event in EOIO (exactly once in order) but just need it to be EO (exactly once) thus, I am utilising the transactional RFC (tRFC) unit.
In the RFC function module, implement your custom logic. In my case here, I am triggering an ABAP proxy that calls to a SAP PO to publish the message into a JMS topic.
You will require the following authorizations for the setup.
- For bgRFC configuration, you need authorization object S_BGRFC.
- For bgRFC Supervisor User, you need authorization object S_RFC.
For the setup:
1. Creating a Supervisor Destination
Supervisor destination is used to get the configuration settings for the bgRFC scheduler and starts or stops the schedulers as required on each application server.
Using the transaction SBGRFCCONF, you can define a supervisor destination.
- Choose the Create symbol on the Define Supervisor Dest tab page.
- Enter the name of the destination to be created.
- Enter the supervisor user name and a password.
- Choose Copy.
2. Maintaining Inbound Destinations
As my use case is to enable the asynchronies between the caller and the called application within the same system (same SID and same client). The Inbound destination and queue prefixes help in compartmentalizing different applications and avoid conflict for applications using the same queue name in the same system.
Using the transaction SBGRFCCONF, you can define an inbound destination.
- Choose the Create symbol on the Define Inbound Dest tab page.
- Enter the name of the inbound destination to be created.
- Select a logon/server group
- Add a queue prefix.
- Choose Save.
3. System, Application and Destination – Specific Settings
Well, referring to the recommendations in SAP 2309399 – How to use SBGRFCCONF effectively?, I have pretty much use the default values for my use case. I would suggest that you do a performance test if you expect huge volume on your end to determine which settings work best for your use case.
How to monitor the bgRFC?
Use the transaction SBGRFCMON to monitor the bgRFC.
For testing purpose, I have inserted a temporary local programmatically after the call so that I will be able to monitor my tRFC unit in the bgRFC monitoring tool. This is required for the initial run or if your inbound destination is empty. You can also opt to lock and unlock the destination inside the bgRFC monitoring tool.
... CALL FUNCTION 'Z_PY_POST_NOTF_OUT' IN BACKGROUND UNIT my_unit EXPORTING i_internal_outbound = i_tab_int_data. " for testing only lock_id = my_unit->delay( 300 ). ...
This my first blog post, thus, apologize for any shortcomings or inaccuracy in the terminology that I might have used. I just hope that this blog post will help anyone who faces the same requirements/scenario/use case and would like to reap the benefits mentioned, you may evaluate the option shared in this blog post. And lastly, I welcome your kind feedback.
I am also planning to put up another blog post for another use case of bgRFC on how to prevent the error due to locking issue when receiving by using the queue mechanism of the bgRFC framework. Stay tuned.