Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

How to rollback after BAPI_TRANSACTION_COMMIT?

Former Member
0 Likes
8,042

Hello!

I have two questions, please. In my dialog transaction I need to update 4 things. If one of them fails, I want to rollback all of them. I thought I could achieve this by putting them all in a function module. My first question is: will that work?

My function module is like this:

PERFORM GOODS_MOVEMENT

PERFORM UPDATE_PRODUCTION_ORDER

PERFORM UPDATE_PURCHASE_ORDER

PERFORM GOODS_MOVEMENT (again)

In my FORM GOODS_MOVEMENT I have CALL FUNCTION 'BAPI_GOODSMVT_CREATE' then 'BAPI_TRANSACTION_COMMIT'.

My second question is: if I need to rollback all updates, how do I do that if I have already done 'BAPI_TRANSACTION_COMMIT' ? I tried leaving that out but If I don't do it the second PERFORM GOODS_MOVEMENT fails.

Thanks for your advice.

Joy

1 ACCEPTED SOLUTION
Read only

Former Member
0 Likes
4,333

see if u r using dailogs( screens) ............y u have opted for bapi's (as bapis post the data directly to database ) ...............no need to use the screens here.

if u want work with screens u can do recording for u r own screen ...and work with bdc ok.

any how [BAPI_TRANSACTION_ROLLBACK] this is the function module to do rollback...................

if u r working with screens u need to use commit work statement if any failure is there do rollback with roll back statement

The ROLLBACK statement cancels the current transaction and starts a new transaction.

Syntax

<rollback_statement> ::= ROLLBACK [WORK]

The ROLLBACK statement implicitly opens a new transaction. Any locks set within the new transaction are assigned to this transaction. The isolation leveldeclared in the CONNECT statement also applies for setting locks in the new transaction.

go thrugh the sample code

types : begin of ty_main,

matnr type bapimathead-material,

mtart type bapimathead-matl_type,

mbrsh type bapimathead-ind_sector,

matkl type bapi_mara-matl_group,

meins type bapi_mara-base_uom,

spras type bapi_makt-langu,

maktx type bapi_makt-matl_desc,

werks type marc-werks,

herkl type marc-herkl,

vkorg type mvke-vkorg,

vtweg type mvke-vtweg,

end of ty_main,

begin of ty_tab,

matnr type mara-matnr,

werks type marc-werks,

end of ty_tab,

begin of ty_error,

matnr type bapimathead-material,

mesg type bapiret2-message,

end of ty_error.

data : it_main type standard table of ty_main with header line,

it_makt type standard table of bapi_makt with header line,

it_tab type standard table of ty_tab with header line,

it_error type standard table of ty_error with header line,

it_mathead type bapimathead,

it_clientdata type bapi_mara,

it_clientdatax type bapi_marax,

it_plantdata type bapi_marc,

it_plantdatax type bapi_marcx,

it_salesdata type bapi_mvke,

it_salesdatax type bapi_mvkex,

it_return type bapiret2,

v_count type i,

v_success type i,

v_error type i.

selection-screen begin of block b1.

parameter : p_file type rlgrap-filename obligatory.

selection-screen end of block b1.

at selection-screen on value-request for p_file.

call function 'F4_FILENAME'

exporting

program_name = syst-cprog

dynpro_number = syst-dynnr

field_name = ' '

importing

file_name = p_file.

start-of-selection.

perform get_data.

end-of-selection.

if not it_error[] is initial.

describe table it_error lines v_error.

endif.

perform get_summary.

&----


*& Form get_data

&----


  • text

----


form get_data .

data : lv_infile type string.

lv_infile = p_file.

call function 'GUI_UPLOAD'

exporting

filename = lv_infile

filetype = 'ASC'

has_field_separator = 'X'

tables

data_tab = it_tab

exceptions

file_open_error = 1

file_read_error = 2

no_batch = 3

gui_refuse_filetransfer = 4

invalid_type = 5

no_authority = 6

unknown_error = 7

bad_data_format = 8

header_not_allowed = 9

separator_not_allowed = 10

header_too_long = 11

unknown_dp_error = 12

access_denied = 13

dp_out_of_memory = 14

disk_full = 15

dp_timeout = 16

others = 17.

if sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

else.

select matnr

mtart

mbrsh

matkl

meins

spras

maktx

werks

herkl

vkorg

vtweg

into table it_main

from zanand_bapi_view

for all entries in it_tab

where matnr = it_tab-matnr

and werks = it_tab-werks

and spras = sy-langu.

if sy-subrc = 0.

describe table it_main lines v_count.

perform get_bapi.

endif.

endif.

endform. " get_data

&----


*& Form get_bapi

&----


  • text

----


form get_bapi .

loop at it_main.

it_mathead-material = it_main-matnr.

it_mathead-ind_sector = it_main-mbrsh.

it_mathead-matl_type = it_main-mtart.

it_clientdata-matl_group = it_main-matkl.

it_clientdata-base_uom = it_main-meins.

it_clientdatax-matl_group = 'X'.

it_clientdatax-base_uom = 'X'.

it_plantdata-plant = it_main-werks.

it_plantdata-countryori = it_main-herkl.

it_plantdatax-plant = it_main-werks.

it_plantdatax-countryori = 'X'.

it_salesdata-sales_org = it_main-vkorg.

it_salesdata-distr_chan = it_main-vtweg.

it_salesdatax-sales_org = it_main-vkorg.

it_salesdatax-distr_chan = it_main-vtweg.

it_makt-langu = it_main-spras.

it_makt-matl_desc = it_main-maktx.

append it_makt.

clear it_makt.

call function 'BAPI_MATERIAL_SAVEDATA'

exporting

headdata = it_mathead

clientdata = it_clientdata

clientdatax = it_clientdatax

plantdata = it_plantdata

plantdatax = it_plantdatax

importing

return = it_return

tables

materialdescription = it_makt.

if it_return-type = 'S'.

call function 'BAPI_TRANSACTION_COMMIT'.

  • EXPORTING

  • WAIT = WAIT

  • IMPORTING

  • RETURN = RETURN.

else.

it_error-matnr = it_main-matnr.

it_error-mesg = it_return-message.

append it_error.

clear it_error.

call function 'BAPI_TRANSACTION_ROLLBACK'.

  • IMPORTING

  • RETURN = RETURN.

endif.

clear : it_main,it_mathead,it_clientdata,it_clientdatax,it_plantdata,it_plantdatax,it_salesdata,it_salesdatax,it_return.

refresh it_makt.

endloop.

endform. " get_bapi

&----


*& Form get_summary

&----


  • text

----


form get_summary .

v_success = v_count - v_error.

write : /10 'Total Reocrds: ',v_count,

/10 'Successful Records: ',v_success.

if not v_error is initial.

write :/10 'Error Records : ',v_error.

skip 3.

loop at it_error.

write :/10 it_error-matnr,

/10 it_error-mesg.

clear it_error.

endloop.

endif.

reward points if helpful.

15 REPLIES 15
Read only

Former Member
0 Likes
4,334

see if u r using dailogs( screens) ............y u have opted for bapi's (as bapis post the data directly to database ) ...............no need to use the screens here.

if u want work with screens u can do recording for u r own screen ...and work with bdc ok.

any how [BAPI_TRANSACTION_ROLLBACK] this is the function module to do rollback...................

if u r working with screens u need to use commit work statement if any failure is there do rollback with roll back statement

The ROLLBACK statement cancels the current transaction and starts a new transaction.

Syntax

<rollback_statement> ::= ROLLBACK [WORK]

The ROLLBACK statement implicitly opens a new transaction. Any locks set within the new transaction are assigned to this transaction. The isolation leveldeclared in the CONNECT statement also applies for setting locks in the new transaction.

go thrugh the sample code

types : begin of ty_main,

matnr type bapimathead-material,

mtart type bapimathead-matl_type,

mbrsh type bapimathead-ind_sector,

matkl type bapi_mara-matl_group,

meins type bapi_mara-base_uom,

spras type bapi_makt-langu,

maktx type bapi_makt-matl_desc,

werks type marc-werks,

herkl type marc-herkl,

vkorg type mvke-vkorg,

vtweg type mvke-vtweg,

end of ty_main,

begin of ty_tab,

matnr type mara-matnr,

werks type marc-werks,

end of ty_tab,

begin of ty_error,

matnr type bapimathead-material,

mesg type bapiret2-message,

end of ty_error.

data : it_main type standard table of ty_main with header line,

it_makt type standard table of bapi_makt with header line,

it_tab type standard table of ty_tab with header line,

it_error type standard table of ty_error with header line,

it_mathead type bapimathead,

it_clientdata type bapi_mara,

it_clientdatax type bapi_marax,

it_plantdata type bapi_marc,

it_plantdatax type bapi_marcx,

it_salesdata type bapi_mvke,

it_salesdatax type bapi_mvkex,

it_return type bapiret2,

v_count type i,

v_success type i,

v_error type i.

selection-screen begin of block b1.

parameter : p_file type rlgrap-filename obligatory.

selection-screen end of block b1.

at selection-screen on value-request for p_file.

call function 'F4_FILENAME'

exporting

program_name = syst-cprog

dynpro_number = syst-dynnr

field_name = ' '

importing

file_name = p_file.

start-of-selection.

perform get_data.

end-of-selection.

if not it_error[] is initial.

describe table it_error lines v_error.

endif.

perform get_summary.

&----


*& Form get_data

&----


  • text

----


form get_data .

data : lv_infile type string.

lv_infile = p_file.

call function 'GUI_UPLOAD'

exporting

filename = lv_infile

filetype = 'ASC'

has_field_separator = 'X'

tables

data_tab = it_tab

exceptions

file_open_error = 1

file_read_error = 2

no_batch = 3

gui_refuse_filetransfer = 4

invalid_type = 5

no_authority = 6

unknown_error = 7

bad_data_format = 8

header_not_allowed = 9

separator_not_allowed = 10

header_too_long = 11

unknown_dp_error = 12

access_denied = 13

dp_out_of_memory = 14

disk_full = 15

dp_timeout = 16

others = 17.

if sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

else.

select matnr

mtart

mbrsh

matkl

meins

spras

maktx

werks

herkl

vkorg

vtweg

into table it_main

from zanand_bapi_view

for all entries in it_tab

where matnr = it_tab-matnr

and werks = it_tab-werks

and spras = sy-langu.

if sy-subrc = 0.

describe table it_main lines v_count.

perform get_bapi.

endif.

endif.

endform. " get_data

&----


*& Form get_bapi

&----


  • text

----


form get_bapi .

loop at it_main.

it_mathead-material = it_main-matnr.

it_mathead-ind_sector = it_main-mbrsh.

it_mathead-matl_type = it_main-mtart.

it_clientdata-matl_group = it_main-matkl.

it_clientdata-base_uom = it_main-meins.

it_clientdatax-matl_group = 'X'.

it_clientdatax-base_uom = 'X'.

it_plantdata-plant = it_main-werks.

it_plantdata-countryori = it_main-herkl.

it_plantdatax-plant = it_main-werks.

it_plantdatax-countryori = 'X'.

it_salesdata-sales_org = it_main-vkorg.

it_salesdata-distr_chan = it_main-vtweg.

it_salesdatax-sales_org = it_main-vkorg.

it_salesdatax-distr_chan = it_main-vtweg.

it_makt-langu = it_main-spras.

it_makt-matl_desc = it_main-maktx.

append it_makt.

clear it_makt.

call function 'BAPI_MATERIAL_SAVEDATA'

exporting

headdata = it_mathead

clientdata = it_clientdata

clientdatax = it_clientdatax

plantdata = it_plantdata

plantdatax = it_plantdatax

importing

return = it_return

tables

materialdescription = it_makt.

if it_return-type = 'S'.

call function 'BAPI_TRANSACTION_COMMIT'.

  • EXPORTING

  • WAIT = WAIT

  • IMPORTING

  • RETURN = RETURN.

else.

it_error-matnr = it_main-matnr.

it_error-mesg = it_return-message.

append it_error.

clear it_error.

call function 'BAPI_TRANSACTION_ROLLBACK'.

  • IMPORTING

  • RETURN = RETURN.

endif.

clear : it_main,it_mathead,it_clientdata,it_clientdatax,it_plantdata,it_plantdatax,it_salesdata,it_salesdatax,it_return.

refresh it_makt.

endloop.

endform. " get_bapi

&----


*& Form get_summary

&----


  • text

----


form get_summary .

v_success = v_count - v_error.

write : /10 'Total Reocrds: ',v_count,

/10 'Successful Records: ',v_success.

if not v_error is initial.

write :/10 'Error Records : ',v_error.

skip 3.

loop at it_error.

write :/10 it_error-matnr,

/10 it_error-mesg.

clear it_error.

endloop.

endif.

reward points if helpful.

Read only

Former Member
0 Likes
4,333

Hello Ramyav,

Thanks for your reply. So, you are saying to CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. The problem is the first goods movement update may be successful and I won't know that I have to rollback until all the other updates are complete. At that time, can I still do 'BAPI_TRANSACTION_ROLLBACK'? Will it know which transaction to rollback?

Joy

Read only

Former Member
0 Likes
4,333

check the bapireturn parameter .................and collect all the error records (with msg type 'E' ] and do rollback...................

firstly,....bapi wont update the error records ..............u can directly view the error records in bapireturn table...................my advice is to use BAPITET2 (bcoz it will capture error record and record number also so that u can easily identify)...........

if u r using bapi to create goods movement ............no need work on screens.......

u can find each and every field regarding to goods movement in bapi structures

no need to create screens with fields ....

reward points if helpful.

Read only

Former Member
0 Likes
4,333

Hello Ramyav,

Thanks again. I think you are talking about rolling back if the bapi is not successful. I am asking about rolling back a previously successful update. I am thinking that I cannot do that. I may have to use BDC instead. Do you know the answer to my first question. That is, how can I rollback 4 updates if, say , the last one is not successful. I tried putting them all in a function module but that does not seem to work. It is still keeping the successful updates even if the last one is not successful. Will it work if I call the FM in UPDATE TASK?

Thanks,

Joy

Read only

Former Member
0 Likes
4,333

I have done something similar to this in batch input. Not sure if it would work with BAPIS.

Call the first update and if successful, commit it.

Call the second update. If successfule, commit it; otherwise, rollback and then reverse the first update.

Continue...

Rob

Read only

Former Member
0 Likes
4,333

Rob.

I think I will have to resort to BDC, as you have done. I don't know how to do it if I have already committed a bapi.

thanks for your reply.

Joy

Read only

0 Likes
4,333

Well, you would have to do it the same way. Call the BAPI so as to undo the cahnges you made.

Rob

Read only

Former Member
0 Likes
4,333

Rob,

Yes, I could. I just don't want to have multiple, in this case, goods movements back and forth. I would rather the update rolled back.

Joy

Read only

0 Likes
4,333

Unfortunately (or fortunately) a commit is a commit. There's not much you can do about it.

Rob

Read only

RaymondGiuseppi
Active Contributor
0 Likes
4,333

After a commit (or bapi_transaction_commit which is a BAPi that do a commit and a refresh of itab) you can no monger reverse the database change with rollback or bapi_transaction_rollback. So you need to do a new bapi call that reverse movement or cancel change of orders.

call BAPI1
if ok 
- commit
else 
- rollback
- exit
endif
call BAPI2
if ok
- commit
else 
- rollback
- call BAPI1 reversed
- pray!
- commit
- exit
endif

And remeber if third BAPI fails, you have two reverse call to execute, and what if the second of these reverse call fails...

So first, make all what is humanly (and budgetary) possible to insure that each call willl succeed, control data, check locks and so on.

Regards

Read only

Former Member
0 Likes
4,333

Raymond,

I see your point. I especially like the praying part....

thanks for your reply,

Joy

Read only

Former Member
0 Likes
4,333

The best way is to check the return table if the return table doesn't contain any error messages i.e. when return-msgty ne 'E' then only call the FM BAPI_TRANSACTION_COMMIT, else you an ROLLBACK WORK. or do the necessary action instead.

Read only

Former Member
0 Likes
4,333

Hi,

I didn't get why are you

just don't fire commit work until everything is fine.

and try to read SAP LUW http://help.sap.com/erp2005_ehp_04/helpdata/EN/41/7af4c2a79e11d1950f0000e82de14a/frameset.htm



DATA: lv_tid TYPE ARFCTID.

CALL FUNCTION 'TRANSACTION_BEGIN'
 IMPORTING
   TRANSACTION_ID       = lv_tid

          .
PERFORM GOODS_MOVEMENT.
*Check for an error here or inside the perform
* and put this code there

IF <your logical expression here>."in case of an error
* this fires ROLLBACK
  CALL FUNCTION 'TRANSACTION_ABORT'
    EXPORTING
      transaction_id       = lv_tid
            .
ENDIF.

PERFORM UPDATE_PRODUCTION_ORDER.
* another check for errors
IF <your logical expression here>."in case of an error
* this fires ROLLBACK
  CALL FUNCTION 'TRANSACTION_ABORT'
    EXPORTING
      transaction_id       = lv_tid
            .
ENDIF.

PERFORM UPDATE_PURCHASE_ORDER.
* another check for errors
IF <your logical expression here>."in case of an error
* this fires ROLLBACK
  CALL FUNCTION 'TRANSACTION_ABORT'
    EXPORTING
      transaction_id       = lv_tid
            .
ENDIF.

PERFORM GOODS_MOVEMENT.
* another check for errors
IF <your logical expression here>."in case of an error
* this fires ROLLBACK
  CALL FUNCTION 'TRANSACTION_ABORT'
    EXPORTING
      transaction_id       = lv_tid
            .
 ELSE."No errors
* this fires commit work
   CALL FUNCTION 'TRANSACTION_END'
     EXPORTING
       transaction_id       = lv_tid
             .

ENDIF.

Read only

Former Member
0 Likes
4,333

Hi Joy,

I Actually Haven't worked a lot in BAPI's but this what I have seen While Surfing through Other Forums:


LOOP AT W_BAPIRET2
   WHERE TYPE = 'E'.

   WRITE:/ '* Erreur : Probleme de mise a jour des ' , 'caractéristiques'.
   WRITE:/ ' -> Message SAP : ' , w_bapiret2-message.

ENDLOOP.
IF sy-subrc eq 0.
* Do your rollback

ELSE.
* do your commit

ENDIF.

Just Check It May be Helpful!!!!!!!!!!!!!

Read only

Former Member
0 Likes
4,333

Calling the function BAPI_TRANSACTION_COMMIT uses 1. WAIT (Exporting) and 2. RETURN (importing) use these 2 when ur call this function pass 'X' in wait and pass an empty structure same as BAPIRETURN2 table for RETURN importing parameter. Then check whether the return-msgty = 'E' means error while commit. and then ROLLBACK WORK if this true or else COMMIT WORK is already executed in the above bapi function itself.

Hope this helps you.