How to submit the report from V2 update process?
Hello mates,
I believe this post will seem really strange solution for most of gurus here but there was the only solution i have found to solve the task.
Sometimes you have set of programs ( standard or client but that were written many years ago ), that are working well and don’t need to be redesigned to new class-based apporach. And your logic have the requirement to run these reports from update tasks.
Why do I have such strange requirement? Let’s say we have a report that regenerates someting with COMMIT WORK inside it. And I have an update process that should include also this regeneration finally. And this call should be done only after DB commit, and of course it shouldn’t be called in the case of errors. And yes – it takes a lot of time that’s why we call update FM in V2.
So initially we are here:
So if you try to submit the report directly t from the SET_STATUS_FM that has been run in update task you will definetely get the short dump. Some of my team mates were even sure there were no way to do this without getting the dump but we finally handled that. Calling report using via job is not also possible here.
After spending some time on researching I figured out that it’s possible to submit the report from transactional RFC. So I prepared some test program to prove that. It was looking like this:
Next step was assumed just to call this UPDATE_INDEX_RFC from SET_STATUS_FM but this is prohibited to call tRFC from update processes and you will also get a dump here. But the solution was found – and the name is bgRFC.
Frankly speaking I had never considered this technique providing by SAP before because always thinked it’s the same qRFC and tRFC but class-based designed. But that’s not like this. There is at least really powerful features that bgRFC provides – you can call it from update processes.
I also skip the bgRFC functionality description. All the related information you can find here:
bgRFC (Background Remote Function Call) – Components of SAP Communication Technology – SAP Library
So I configured bgRFC according to provided help. Also I created new inbound destination. Then I changed the test program with the code like this:
try. .
data(lo_dest) = cl_bgrfc_destination_inbound=>create( 'ZUPDATE_INDEX' ).
data(lo_unit) = lo_dest->create_qrfc_unit( ).
lo_unit->add_queue_name_inbound(
exporting
queue_name = 'ZUPDATE_INDEX'
).
CALL FUNCTION 'ZUPDATE_INDEX_BGRFC' IN BACKGROUND unit lo_unit.
catch cx_bgrfc_invalid_destination.
endtry.
And the sequence of calls became like this:
That worked well also and the last step was to combine all the calls in one chain:
You probably are thinking now I’m crazy and look at this as at piece of trash. But if it is, I would be grateful to receive an alternative way to do this =).
In anyway we achieved several goals at the same moment:
- we reused the report as we have it. No code refactoring inside.
- If update process fails bgRFC doesn’t start
- bgRFC starts only after commit statement
- bgRFC uses already updated database
There is at least one point I would pay attention to also:
- If bgRFC crashes the update is not being rolled back.
But the last point was OK for us so we didn’t care about that. It’s similar to scheduled report run as a job.
I hope this information could be helpful for some of you.
Best regards,
Petr Plenkov.
Excellent post!
I want to add just one point:
CALL FUNCTION..IN BACKGROUND UNIT... statement also needs a COMMIT WORK (just like CALL FUNCTION...IN BACKGROUND TASK...), otherwise its useless.
COMMIT WORK is not allowed inside an update function module.
But here in this case, you do not have a COMMIT WORK inside your update function module and the bgRFC gets created only if the update task was successful (and there is a COMMIT WORK issued by the system at the end of successful update task execution).
One question:
You could have submitted the report directly from inside the function module specified in the bgRFC unit (there is no need for the intermediate tRFC call CALL FUNCTION IN BACKGROUND TASK). Is there a reason why you did not want to do this?
Thanks a lot for your rresponse!
actually I couldnt submit the report from bgrfc directly.
but I will try to do this again.
have you tried to do these steps in v2 process or in v1? Which bgrfc did you use? Q or T?
Actually not!
I happened to hit on this blog post accidentally and it was very interesting to find how bgRFC is being used in this setup.
If I understand your solution correctly, you could do this in V1 or V2 - it does not matter.
Further, from within a bgRFC unit it should be possible to submit a report (just like you do inside a function module specified in the tRFC entry).
There is functionally no difference between a tRFC entry and a bgRFC type T unit.
This is why I asked such question (and also you could do with one step less 🙂 ).
the standard solution for such case is to schedule your report as a background job that starts on event. you could create new event in SM62 / SM64 and then just raise it whenever you want with function BP_EVENT_RAISE or cl_batch_event=>raise. You could pass job parameter and get it with GET_JOB_RUNTIME_INFO in scheduled report. the negative side it might be required to create a wrap for report you're calling.