1. What is this all about?
I found some interesting facts behind the workflow event mechanism. Why should an open SQL statement “COMMIT WORK” should be defined/included after event is raised through ABAP program or from a Webdynpro component etc?
Then, found the answer that it’s because of the way workflow handles its calls through tRFC (transactional Remote Function Call) mechanism.
“The workflow runtime system always executes its tRFC (transactional RFC) calls on the logical destination WORKFLOW_LOCAL_xxx (xxx stands for the three-digit number of the client).”
The above logical destination can be observed from the transaction SM59 under logical destinations folder. The logical destination will be created automatically, when you execute the activity configure RFC destination from SWU3 transaction. A background user WF-BACTH user will be assigned to the logical destination
The logical destination is client specific. So, make sure this activity has to be executed explicitly on each client.
2. Brief background about tRFC (transactional Remote Function Call)
The term “transactional” implies that the call to the function module is treated with Atomicity Property i.e. either whole transaction would be executed or if any failure occurred during the execution of the transaction then nothing is executed.
2.1 Significant notes about tRFC
- Data can be transferred to other systems reliably by using the tRFC mechanism.
- You have to invoke a function module by using CALL FUNCTION statement with addition, IN BACKGROUND TASK to make sure the call is a tRFC.
- LUWs (logical units of work) are created for calls that are scheduled to run in background tasks. Each logical unit work is assigned with one unique transaction ID.
- The additions DESTINATION and AS A SEPARATE UNIT are optional. If destination is not mentioned then it considers NONE. The significance of the addition AS A SEPARATE UNIT is that when a function module is called with this addition then a new context of the whole function group is used. Consider as a new instance of the entire function group is created.
- Function module which is called by this mechanism should not have any exporting parameters in the call.
- Function module which is invoked by using this mechanism is called and executed exactly one time in mentioned destination.
- The tRFC component stores the called RFC function together with the corresponding data in the database of the SAP system, including a unique transaction identifier (TID).
- All tRFC’s with a single destination that occur between one COMMIT WORK and the next belong to a single logical unit of work (LUW).
2.2 How tRFC Calls are handled?
- When the transactional call is made, the name of the called function, together with the destination and the actual parameters given in parameter list, are registered for the current SAP LUW in the database tables ARFCSSTATE and ARFCSDATA of the current SAP system under a unique transaction ID.
- Following this registration, the program making the call is continued by way of the statement CALL FUNCTION.
- When executing the COMMIT WORK statement, the function modules registered for the current SAP LUW are started in the sequence in which they were registered.
- The statement ROLLBACK WORK deletes all previous registrations of the current SAP LUW.
3. Coming Back to Workflow Event Linkage Mechanism
When a workflow has to act like a receiver after creation or specific changes done to the Business objects (Sales Order, Leave Request, Purchase Order etc…). For this, the respective business object and event needs to be activated. This activation is defined in the transaction SWE2. While configuring the event linkage you have the option of defining Receiver Function Module, Check Function Module and Receiver Type Function Module. When an event is raised through ABAP Programs by using SAP_WAPI_CREATE_EVENT or the Event class the following steps are executed in below sequence.
- If a receiver type function module is entered, it is called to determine the receiver type.
- If a check function module is entered it is called. If its execution terminates with an exception, the linkage is not executed.
- The receiver function module is called with the parameters event, receiver type and event container.
Since the asynchronous RFC for calling the receiver function module is not triggered until after the next COMMIT WORK, you must initiate the command COMMIT WORK in your application after the method for creating an event is called in order for the events to actually be created. The database commit performed automatically with a screen change does not trigger the asynchronous RFC.
3.1 How it works?
Consider a scenario where you try to raise an event either by using SAP_WAPI_CREATE_EVENT the following actions are performed in the background.
The call of the function module is as follows:
- CALL FUNCTION ‘SAP_WAPI_CREATE_EVENT’
object_type = ‘ZTEST_BO’
object_key = ‘WS90000021’
event = ‘CREATED’
commit_work = ‘ ‘.
- Initially the a transaction is created , since a tRFC call is executed as a whole transaction, by using the below piece of code it creates a transaction by exporting the value passed to commit_work parameter to the function module.
- CALL METHOD cl_swf_utl_transaction=>create
im_commit_work_control = commit_work
re_transaction = lv_transaction.
- Later it tries to get the event handler object by passing the respective BOR/Class Name, key and event name, so that it can raise the respective event
- The event creation is done by the class cl_swf_evt_event_manager and its instance method raise_event.
- In the above class method as mentioned it tries to execute the receiver type function module if mentioned, next to it Check function module is executed if mentioned.
- The receiver function module is called by using tRFC mechanism. In this way the receiver function module is executed only once on the logical destination.
- If parameter COMMIT_WORK is passed ‘X’, then the event is raised immediately, this is because at one point during the execution the system executes the open SQL statement COMMIT_WORK then, created transaction is completed or else the execution of the receiver function module or completion of the transaction is postponed till the explicit COMMIT WORK is executed.
- IF commit_work IS NOT INITIAL.
CALL METHOD lv_transaction->commit( ).
Conflicts in V1 update Mechanism.
“During the processing of an update function module in the update work process, the statements SUBMIT, CALL DIALOG, CALL SCREEN, CALL TRANSACTION, COMMIT WORK, and ROLLBACK WORK, as well as all other statements that create a database commit, must not be executed.”
The event cannot be raised in update function module, because an explicit commit work is already executed to start the Update task and again in order to raise a workflow event, we should need another more commit work inside the update function module, to register and call the receiver function module in the respective logical system, which conflicts with the above statement.
This could be one of the reasons why the raising event of workflow is not done in update task. Instead most of the programming guidelines suggest that the workflow event raising should happen before the end of transaction.