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

BAPI Lock issue

Former Member
0 Likes
3,618

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.

10 REPLIES 10
Read only

Former Member
0 Likes
1,847

When testing the locks using the enqueue function, try setting the _WAIT parameter to 'X'.

Rob

Read only

0 Likes
1,847

Hi,

Thanks. But where is this parameter?

Nathan.

Read only

0 Likes
1,847

It should be an importing parameter for the enqueue function.

Rob

Read only

former_member194669
Active Contributor
0 Likes
1,847

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®

Read only

Clemenss
Active Contributor
0 Likes
1,847

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

Read only

Former Member
0 Likes
1,847

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.

Read only

Former Member
0 Likes
1,847

Did you try this with the enqueue function as I suggested?

Rob

Read only

Former Member
0 Likes
1,847

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.

Read only

Clemenss
Active Contributor
0 Likes
1,847

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

Read only

Former Member
0 Likes
1,847

Hi Clemens,

Thanks for the code. Will try it and get back. Thanks once again.

Nathan.