2014 May 16 10:24 PM
I have a question about how to control the value of sy-subrc that is returned from a "commit work and wait" statement used to end the LUW and trigger an update function module (for synchronous update). Here is my code for the update function module call and the commit (note: this code is contained withing a custom inbound IDOC process code) :
CALL FUNCTION 'Z_UPDATE_IMS' IN UPDATE TASK
EXPORTING
imt_ims = gt_ims.
COMMIT WORK AND WAIT.
IF sy-subrc NE 0.
ROLLBACK WORK.
w_status = '68'.
w_msgv1 = 'IMS Invoice Load Failed'(t04).
ELSE.
w_status = '53'.
w_msgv1 = 'IMS Invoice(s) Loaded Successfully'(t05).
ENDIF.
Here is the relevant code from withing function "Z_UPDATE_IMS" which is set as an "Update Module - Start Immediately":
IF NOT lts_insert[] IS INITIAL.
TRY.
INSERT zims FROM TABLE lts_insert.
CATCH cx_sy_open_sql_db.
MESSAGE a004(zar_ap).
ENDTRY.
ENDIF.
If the d/b insert statement above results in a duplicate record insert, the exception in caught and I issue an abort message (as I was trained in my ABAP certification) to cause a d/b rollback. However, the code after the "commit work and wait" statement is never executed. It appears the update task and the calling program are both aborted.
My question, in the above situation, what is needed so that the "commit work and wait" returns a non-zero sy subrc if the database insert fails in the update task. Note: the use of synchronous update is essential because I need to know the results of the d/b update in order to set the proper IDOC status.
Your advice is greatly appreciated.
R/
Jim Moore
2014 May 17 1:14 AM
Hi Jim,
When commit is executed the program enters the update mode. You can't commit or rollback in update mode, it's already done.
Also you're in a synchronous call inside the function, so naturally if you abort the function so does the main program aborts.
I'm having a hard time understanding your code. Why isn't just something like:
CALL FUNCTION 'Z_UPDATE_IMS'
EXPORTING
imt_ims = gt_ims
exceptions
err_rollback = 1.
IF sy-subrc NE 0.
ROLLBACK WORK.
w_status = '68'.
w_msgv1 = 'IMS Invoice Load Failed'(t04).
ELSE.
commit work. "shouldn't be necessary...
w_status = '53'.
w_msgv1 = 'IMS Invoice(s) Loaded Successfully'(t05).
ENDIF.
and in function:
IF NOT lts_insert[] IS INITIAL.
TRY.
INSERT zims FROM TABLE lts_insert.
CATCH cx_sy_open_sql_db.
raise err_rollback.
ENDTRY.
ENDIF.
Regards,
Edgar
2014 May 17 1:14 AM
Hi Jim,
When commit is executed the program enters the update mode. You can't commit or rollback in update mode, it's already done.
Also you're in a synchronous call inside the function, so naturally if you abort the function so does the main program aborts.
I'm having a hard time understanding your code. Why isn't just something like:
CALL FUNCTION 'Z_UPDATE_IMS'
EXPORTING
imt_ims = gt_ims
exceptions
err_rollback = 1.
IF sy-subrc NE 0.
ROLLBACK WORK.
w_status = '68'.
w_msgv1 = 'IMS Invoice Load Failed'(t04).
ELSE.
commit work. "shouldn't be necessary...
w_status = '53'.
w_msgv1 = 'IMS Invoice(s) Loaded Successfully'(t05).
ENDIF.
and in function:
IF NOT lts_insert[] IS INITIAL.
TRY.
INSERT zims FROM TABLE lts_insert.
CATCH cx_sy_open_sql_db.
raise err_rollback.
ENDTRY.
ENDIF.
Regards,
Edgar
2014 May 17 7:35 AM
Hi Jim
No need to rollback after commit. When you will raise abort in FM system will perform auto roll back
Nabheet
2014 May 19 2:16 PM
Edgar,
Thanks for the feedback. I'm performing the d/b updates in an update function module because there are several updates that must occur in the same LUW. I only showed one of these updates in my original post for the sake of simplicity.
You said: "you're in a synchronous call inside the function, so naturally if you abort the function so does the main program aborts"... I guess I don't see this as obvious as you. I would expect the update task to abort. I expected this to result in a sy-subrc = 4 for the "commit work and wait" statement in the calling program per SAP help...
System fields
| sy-subrc | Meaning |
| 0 | You have specified the AND WAIT addition, and the updating of the update function modules was successful. |
| 4 | You have specified the AND WAIT addition, and the updating of the update function modules was not successful. |
I re-reviewed this help documentation and noticed that it only references the "and wait" addition in the context of "Triggering an internal event for the Persistence Service of the Object Services". I'm currently not familiar with "Persistence Services", is this a technique that may address my issue?
The essence of my question... is there a way, other than issuing an abort in the update task, that I can trigger the sy-subrc = 4 in the calling program?
Nabheet,
Yes, you are correct that the "rollback work" statement is redundant as the abort message will take care of this. I was experimenting with other message types in my update module and forgot to remove the rollback statement when I returned the messages to type "A". I'm pretty certain this is not causing my issue as the abort currently stops both the update task and the calling program, thus the "rollback work" statement never actually gets called.
Thank you both for the feedback,
R/
Jim Moore
2014 May 19 4:49 PM
Edgar,
You were correct, I didn't realize, until now, that I could do multiple on-line d/b updates within a single d/b LUW and still roll back all of them if any failures occured... as long as no implicit d/b commit occurs. I was under the mistaken impression that I had to use an update task to bundle together multiple d/b updates. Lesson learned, update task is only need for performance reasons or when LUW must span multiple screen changes (implicit d/b commits).