‎2007 Jul 06 4:19 PM
Hi Friends,
I have a situation where several instance of a workflow gets created at one time which as a part of the process calls a BAPI and updates a table. Only few instances could update the table successfully (Sometimes none). Rest of them couldnt. The BAPIRETURN message says 'E-PV100-Business Event nnnn is currently locked; Try again later'. I tried to call BAPI_TRANSACTION_COMMIT after the BAPI call. It didnt help. I tried to read all the locks for the user using FM ENQUE_READ and delete them using FM ENQUE_DELETE before and after the BAPI call. It doesnt help either.
How can this be handled? Prompt replies would be appreciated and rewarded suitably.
Thanks in advance.
Nathan.
‎2007 Jul 06 4:27 PM
When testing the locks using the enqueue function, try setting the _WAIT parameter to 'X'.
Rob
‎2007 Jul 06 4:30 PM
‎2007 Jul 06 4:33 PM
It should be an importing parameter for the enqueue function.
Rob
‎2007 Jul 06 4:39 PM
Hi,
Try to call after BAPI_TRANSACTION_COMMIT
call function 'ENQUE_SLEEP'
exporting
seconds = ntime. "<< give seconds to sleep
after the BAPI call. May this will help you.
aRs
Message was edited by:
a®
‎2007 Jul 06 5:00 PM
Hi Nathan
Function BAPI_TRANSACTION_COMMIT has a Parameter WAIT. Call with WAIT = 'X' and it should be OK - although it takes more time.
Regards,
Clemens
‎2007 Jul 06 9:12 PM
Hi,
I tried BAPI_TRANSACTION_COMMIT with WAIT = SPACE as well as WAIT = 'X'. Either case the workflow doesnt proceed after the BAPI step and the records are not updated.
Any other way?
Thanks
Nathan.
‎2007 Jul 06 9:22 PM
Did you try this with the enqueue function as I suggested?
Rob
‎2007 Jul 06 9:43 PM
Hi Rob,
Yes i tried that as well. I called ENQUEUE_E_TABLE before BAPI call, passing the table name and WAIT = 'X' and called DEQUEUEE_TABLE. Still no luck.
Thanks
Nathan.
‎2007 Jul 08 2:43 PM
Hi Nathan,
if COMMIT and WAIT does not help, a COMMIT without work has been issued before. Many not too experienced/responsible developers tend to issue COMMIT WORKS in any kind of user exit just to make sure that their specific changes get written to the database. And you have to survive with the results.
What you could do is check the locks and do a loop before calling BAPI as long as the object is locked. Here's some stone-old code we used for material updates:
FORM WARTEN_VERBUCHER
USING P_MAX_WAIT_SECONDS TYPE I
CHANGING P_SUBRC LIKE SY-SUBRC.
DATA:
L_ENDTIME LIKE SY-UZEIT,
L_TABIX LIKE SY-TABIX,
L_TRIES TYPE I,
L_SUCCESS LIKE SY-SUBRC,
L_ANSW TYPE C,
L_TRY_AGAIN LIKE RMCLS-XFLAG VALUE 'X'.
GET TIME.
L_ENDTIME = SY-UZEIT.
ADD P_MAX_WAIT_SECONDS TO L_ENDTIME.
WHILE L_TRY_AGAIN = 'X'.
LOOP AT ITAB.
PERFORM CHECK_LOCK_EMMARCE
USING ZAUF-WERKS ITAB-MATNR CHANGING P_SUBRC.
GET TIME.
IF P_SUBRC <> 0 OR SY-UZEIT >= L_ENDTIME.
EXIT. "Loop
ENDIF. " sy-subrc = 0.
ENDLOOP. " AT itab.
IF P_SUBRC = 0.
CLEAR: L_TRY_AGAIN.
ELSE.
IF SY-UZEIT >= L_ENDTIME .
PERFORM POPUP_TO_CONFIRM_WAIT
USING P_MAX_WAIT_SECONDS CHANGING L_ENDTIME P_SUBRC.
IF P_SUBRC <> 0.
CLEAR L_TRY_AGAIN.
ELSE.
CLEAR P_SUBRC.
ENDIF. " p_subrc <> 0.
ENDIF. " sy-uzeit >= l_endtime.
ENDIF. " p_subrc = 0.
ENDWHILE. " l_try_again = 'X'.
ENDFORM. " WARTEN_VERBUCHER
*&---------------------------------------------------------------------*
*& Form POPUP_TO_CONFIRM_WAIT
*&---------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
* -->P_WAIT_SECONDS
* <--P_ENDTIME
*----------------------------------------------------------------------*
FORM POPUP_TO_CONFIRM_WAIT USING P_WAIT_SECONDS TYPE I
CHANGING P_ENDTIME LIKE SY-UZEIT
P_SUBRC LIKE SY-SUBRC.
DATA:
L_STARTCOLUMN LIKE SY-CUCOL VALUE 10,
L_STARTROW LIKE SY-CUROW VALUE 20,
L_TITLE(35),
L_TEXTLINE1(70),
L_TEXTLINE2(70),
L_ANSW.
L_TITLE = 'Warten auf gesperrte Tabelle'.
L_TEXTLINE1 = 'Tabelle(n) sind zur Zeit gesperrt'.
IF NOT SY-MSGV1 IS INITIAL. "Foreign lock
CONCATENATE L_TEXTLINE1 'durch Benutzer' SY-MSGV1
INTO L_TEXTLINE1 SEPARATED BY SPACE.
ENDIF. " sy-msgv1 IS INITIAL.
WRITE: P_WAIT_SECONDS TO L_TEXTLINE2.
CONDENSE: L_TEXTLINE2.
CONCATENATE:
'Wollen Sie weitere' L_TEXTLINE2 'Sekunden warten?'
INTO L_TEXTLINE2 SEPARATED BY SPACE.
L_STARTCOLUMN = SY-UZEIT+2(2) MOD 30 + 10.
L_STARTROW = SY-UZEIT+2(2) MOD 10 + 3.
CALL FUNCTION 'POPUP_TO_CONFIRM_STEP'
EXPORTING
* DEFAULTOPTION = 'Y'
TEXTLINE1 = L_TEXTLINE1
TEXTLINE2 = L_TEXTLINE2
TITEL = L_TITLE
START_COLUMN = L_STARTCOLUMN
START_ROW = L_STARTROW
* CANCEL_DISPLAY = 'X'
IMPORTING
ANSWER = L_ANSW
EXCEPTIONS
OTHERS = 1.
IF L_ANSW = 'J'. "(!)
GET TIME.
P_ENDTIME = SY-UZEIT.
ADD P_WAIT_SECONDS TO P_ENDTIME.
P_SUBRC = 0.
ELSE.
P_SUBRC = 8.
ENDIF. " l_answ = 'J'. "(!)
ENDFORM. " POPUP_TO_CONFIRM_WAIT
*&---------------------------------------------------------------------*
*& Form CHECK_LOCK_EMMARCE
*&---------------------------------------------------------------------*
* Prüfen ob Sperre gesetzt
* Code teilweise aus RSENQRR2 übernommen
*----------------------------------------------------------------------*
* -->P_WERKS text *
* -->P_MATNR text *
* <--P_SUBRC text *
*----------------------------------------------------------------------*
FORM CHECK_LOCK_EMMARCE
USING VALUE(P_WERKS) LIKE MARC-WERKS
VALUE(P_MATNR) LIKE MARC-MATNR
CHANGING P_SUBRC.
DATA: ENQ LIKE SEQG3 OCCURS 0 WITH HEADER LINE.
DATA: DEL LIKE SEQG3 OCCURS 0 WITH HEADER LINE.
DATA: SELECT_ALL.
DATA: GUSR LIKE SEQG3-GUSR.
DATA: GMODE LIKE SEQG3-GMODE.
DATA: GNAME LIKE SEQG3-GNAME.
DATA: GARG LIKE SEQG3-GARG.
DATA: GTARG LIKE SEQG3-GTARG.
DATA: GOBJ LIKE SEQG3-GOBJ.
DATA: GUNAME LIKE SEQG3-GUNAME.
DATA: GCLIENT LIKE SEQG3-GCLIENT.
DATA: GTCODE LIKE SEQG3-GTCODE.
DATA: GUSE LIKE SEQG3-GUSE.
DATA: GUSEVB LIKE SEQG3-GUSEVB.
DATA: GBCKTYPE LIKE SEQG3-GBCKTYPE..
DATA: GRANULE LIKE SEQTA.
*** initializations ****************************************************
FREE ENQ.
FREE DEL.
CLEAR: P_SUBRC.
* Konvertieren Matnr
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
INPUT = P_MATNR
IMPORTING
OUTPUT = P_MATNR
EXCEPTIONS
OTHERS = 1.
GNAME = 'MARC'.
GOBJ = 'EMMARCE'.
GUNAME = SY-UNAME.
GCLIENT = SY-MANDT.
CONCATENATE SY-MANDT P_MATNR P_WERKS INTO GARG.
* first try via RFC, retry up to 3 times ******************************
DO 3 TIMES.
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
GCLIENT = GCLIENT
GUNAME = GUNAME
GNAME = GNAME
IMPORTING
SUBRC = P_SUBRC
TABLES
ENQ = ENQ
EXCEPTIONS
OTHERS = 1.
IF SY-SUBRC = 0.
EXIT.
ENDIF.
ENDDO.
* if RFC fails read via NFS ********************************************
IF SY-SUBRC <> 0.
CALL FUNCTION 'ENQUE_READ'
EXPORTING
GCLIENT = GCLIENT
GUNAME = GUNAME
GNAME = GNAME
GARG = GARG
IMPORTING
SUBRC = P_SUBRC
TABLES
ENQ = ENQ.
MESSAGE ID '03' TYPE 'W' NUMBER 113.
ENDIF. "sy-subrc <> 0.
LOOP AT ENQ.
CHECK ENQ-GARG(25) = GARG(25).
CHECK ENQ-GOBJ = GOBJ.
SY-MSGV1 = ENQ-GUNAME.
P_SUBRC = 8.
EXIT.
ENDLOOP." AT enq WHERE garg(25) = garg(25) and gobj = 'EMMARCE'.
ENDFORM. " CHECK_LOCK_EMMARCE
Please adapt to your needs; I think as your processes are running in background, you can take out the POPUP_TO_CONFIRM_WAIT. We used it just to have a chance to get out of the waiting loop if someone slept at his terminal...
Regards,
Clemens
‎2007 Jul 09 6:55 AM
Hi Clemens,
Thanks for the code. Will try it and get back. Thanks once again.
Nathan.