インフリー技術情報発信ブログ

ERP(SAP)導入コンサルティング、ABAP開発、ホームページ制作、WEBシステム構築などを手掛ける、株式会社インフリーです。

排他処理について その5

排他処理について、6回目!今回で、ひとまず終わりになります。

今回は、ロック制御用パラメータについて
例は、前々回「排他処理について その3」と同じロックオブジェクト:EZT01です。

ロックオブジェクトを登録すると、3つのロック制御用パラメータが自動的に作られます。
_WAIT
_COLLECT
_SCORP

1. _WAIT
このパラメータは、その名の通り、待ちます。

すでに同じキーでロックされている場合、「X」を渡すとロックが解除されるまで待ちます。
どれくらい待ってくれるかというと、BASISのパラメータ定義:DELERY_MAXに起因するため、決まっていません。
いままでは、5秒程度が多かったように思います

2. _COLLECT
よく「あぁこんなとこで、ロックのためだけにループしたくないなぁ」って思うことありませんか?
それを解消してくれるのが、このパラメータです!!

このパラメータに「X」を渡すと、その時点ではロックされず、情報がたまります。その後、汎用モジュール「FLUSH_ENQUEUE」をコールしたときに、溜まっているロック情報で一括してロックエントリが追加されます。

実際のソースコードは、↓な感じで使います。

  DATA: itab_mat TYPE STANDARD TABLE OF zt01,
        ha_mat   TYPE zt01.

  SELECT matnr werks
    FROM marc
    INTO CORRESPONDING FIELDS OF TABLE itab_mat.

  LOOP AT itab_mat INTO ha_mat.

*— 別の処理中に、ロック情報を貯めておく
*— このタイミングではロックはかかりません
    CALL FUNCTION 'ENQUEUE_EZT01'
      EXPORTING
        matnr          = ha_mat-matnr
        werks          = ha_mat-werks
        _collect       = 'X'
      EXCEPTIONS
        foreign_lock   = 1
        system_failure = 2
        OTHERS         = 3.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

  ENDLOOP.

*— 汎用モジュール「FLUSH_ENQUEUE」をコールしたタイミングで
*— ロックエントリが一括で追加されます
*— ロックエラーは、この汎用モジュールをコールしたときに発生します
  CALL FUNCTION 'FLUSH_ENQUEUE'
    EXCEPTIONS
      foreign_lock   = 1
      system_failure = 2
      OTHERS         = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

大抵の場合、ロックしようとする前に、ロック対象のキー情報を保持する内部テーブルを編集処理等でループしているはずです。そのタイミングで、溜めておけば、もう無駄なループとはおさらばです。

この「FLUSH_ENQUEUE」は、ロックをかけるときだけではなく、ロックを解除するときにも使えます
例えば↓な感じ

  DATA: itab_mat TYPE STANDARD TABLE OF zt01,
      ha_mat   TYPE zt01.

  SELECT matnr werks
    FROM marc
    INTO CORRESPONDING FIELDS OF TABLE itab_mat.

  LOOP AT itab_mat INTO ha_mat.

    CALL FUNCTION 'ENQUEUE_EZT01'
      EXPORTING
        matnr          = ha_mat-matnr
        werks          = ha_mat-werks
        _collect       = space
      EXCEPTIONS
        foreign_lock   = 1
        system_failure = 2
        OTHERS         = 3.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

*— ロックと同時にロック解除を呼びます
*— このタイミングではロックは解除されず、解除対象として
*— 貯められます
    CALL FUNCTION 'DEQUEUE_EZT01'
      EXPORTING
        matnr    = ha_mat-matnr
        werks    = ha_mat-werks
        _collect = 'X'.

  ENDLOOP.

*— 汎用モジュール「FLUSH_ENQUEUE」をコールしたタイミングで
*— ロックエントリが一括で更新され、ロックが解除されます
  CALL FUNCTION 'FLUSH_ENQUEUE'
    EXCEPTIONS
      foreign_lock   = 1
      system_failure = 2
      OTHERS         = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ロック解除は、よく「DEQUEUE_ALL」が用いられますが、一部だけを一括ロック解除したいというときは、便利です。

3. _SCORP

このパラメータは、更新モジュールを使うときに、用いられます。私は、一度も使ったことがないです。
渡す値は、3種類。それぞれの意味は以下の通りです。
   1: ロックをかけたプログラムで解除可能
   2: ロック解除の権利を更新モジュールに渡します。更新モジュールでのみ、解除可能になります
   3: ロックをかけたプログラムと更新モジュールの両方で解除しないと解除されなくなります。

さて、これで排他処理について、終わります。次回は、なにをテーマにするか思案中です

 

インフリー技術情報発信ブログ © 2013 Frontier Theme